Skip to main content
Drupal API
User account menu
  • Log in

Breadcrumb

  1. Drupal Core 11.1.x
  2. AnalyzeServiceReferencesPass.php

class AnalyzeServiceReferencesPass

Run this pass before passes that need to know more about the relation of your services.

This class will populate the ServiceReferenceGraph with information. You can retrieve the graph in other passes from the compiler.

@author Johannes M. Schmitt <schmittjoh@gmail.com> @author Nicolas Grekas <p@tchwork.com>

Hierarchy

  • class \Symfony\Component\DependencyInjection\Compiler\AbstractRecursivePass implements \Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface
    • class \Symfony\Component\DependencyInjection\Compiler\AnalyzeServiceReferencesPass extends \Symfony\Component\DependencyInjection\Compiler\AbstractRecursivePass

Expanded class hierarchy of AnalyzeServiceReferencesPass

2 files declare their use of AnalyzeServiceReferencesPass
NormalInstallerServiceProvider.php in core/lib/Drupal/Core/Installer/NormalInstallerServiceProvider.php
PhpDumper.php in vendor/symfony/dependency-injection/Dumper/PhpDumper.php

File

vendor/symfony/dependency-injection/Compiler/AnalyzeServiceReferencesPass.php, line 33

Namespace

Symfony\Component\DependencyInjection\Compiler
View source
class AnalyzeServiceReferencesPass extends AbstractRecursivePass {
    protected bool $skipScalars = true;
    private ServiceReferenceGraph $graph;
    private ?Definition $currentDefinition = null;
    private bool $lazy;
    private bool $byConstructor;
    private bool $byFactory;
    private array $definitions;
    private array $aliases;
    
    /**
     * @param bool $onlyConstructorArguments Sets this Service Reference pass to ignore method calls
     */
    public function __construct(bool $onlyConstructorArguments = false, bool $hasProxyDumper = true) {
        $this->enableExpressionProcessing();
    }
    
    /**
     * Processes a ContainerBuilder object to populate the service reference graph.
     */
    public function process(ContainerBuilder $container) : void {
        $this->container = $container;
        $this->graph = $container->getCompiler()
            ->getServiceReferenceGraph();
        $this->graph
            ->clear();
        $this->lazy = false;
        $this->byConstructor = false;
        $this->byFactory = false;
        $this->definitions = $container->getDefinitions();
        $this->aliases = $container->getAliases();
        foreach ($this->aliases as $id => $alias) {
            $targetId = $this->getDefinitionId((string) $alias);
            $this->graph
                ->connect($id, $alias, $targetId, null !== $targetId ? $this->container
                ->getDefinition($targetId) : null, null);
        }
        try {
            parent::process($container);
        } finally {
            $this->aliases = $this->definitions = [];
        }
    }
    protected function processValue(mixed $value, bool $isRoot = false) : mixed {
        $lazy = $this->lazy;
        $inExpression = $this->inExpression();
        if ($value instanceof ArgumentInterface) {
            $this->lazy = !$this->byFactory || !$value instanceof IteratorArgument;
            parent::processValue($value->getValues());
            $this->lazy = $lazy;
            return $value;
        }
        if ($value instanceof Reference) {
            $targetId = $this->getDefinitionId((string) $value);
            $targetDefinition = null !== $targetId ? $this->container
                ->getDefinition($targetId) : null;
            $this->graph
                ->connect($this->currentId, $this->currentDefinition, $targetId, $targetDefinition, $value, $this->lazy || $this->hasProxyDumper && $targetDefinition?->isLazy(), ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $value->getInvalidBehavior(), $this->byConstructor);
            if ($inExpression) {
                $this->graph
                    ->connect('.internal.reference_in_expression', null, $targetId, $targetDefinition, $value, $this->lazy || $targetDefinition?->isLazy(), true);
            }
            return $value;
        }
        if (!$value instanceof Definition) {
            return parent::processValue($value, $isRoot);
        }
        if ($isRoot) {
            if ($value->isSynthetic() || $value->isAbstract()) {
                return $value;
            }
            $this->currentDefinition = $value;
        }
        elseif ($this->currentDefinition === $value) {
            return $value;
        }
        $this->lazy = false;
        $byConstructor = $this->byConstructor;
        $this->byConstructor = $isRoot || $byConstructor;
        $byFactory = $this->byFactory;
        $this->byFactory = true;
        if (\is_string($factory = $value->getFactory()) && str_starts_with($factory, '@=')) {
            if (!class_exists(Expression::class)) {
                throw new LogicException('Expressions cannot be used in service factories without the ExpressionLanguage component. Try running "composer require symfony/expression-language".');
            }
            $factory = new Expression(substr($factory, 2));
        }
        $this->processValue($factory);
        $this->byFactory = $byFactory;
        $this->processValue($value->getArguments());
        $properties = $value->getProperties();
        $setters = $value->getMethodCalls();
        // Any references before a "wither" are part of the constructor-instantiation graph
        $lastWitherIndex = null;
        foreach ($setters as $k => $call) {
            if ($call[2] ?? false) {
                $lastWitherIndex = $k;
            }
        }
        if (null !== $lastWitherIndex) {
            $this->processValue($properties);
            $setters = $properties = [];
            foreach ($value->getMethodCalls() as $k => $call) {
                if (null === $lastWitherIndex) {
                    $setters[] = $call;
                    continue;
                }
                if ($lastWitherIndex === $k) {
                    $lastWitherIndex = null;
                }
                $this->processValue($call);
            }
        }
        $this->byConstructor = $byConstructor;
        if (!$this->onlyConstructorArguments) {
            $this->processValue($properties);
            $this->processValue($setters);
            $this->processValue($value->getConfigurator());
        }
        $this->lazy = $lazy;
        return $value;
    }
    private function getDefinitionId(string $id) : ?string {
        while (isset($this->aliases[$id])) {
            $id = (string) $this->aliases[$id];
        }
        return isset($this->definitions[$id]) ? $id : null;
    }

}

Members

Title Sort descending Modifiers Object type Summary Overriden Title Overrides
AbstractRecursivePass::$container protected property
AbstractRecursivePass::$currentId protected property
AbstractRecursivePass::$expressionLanguage private property 1
AbstractRecursivePass::$inExpression private property
AbstractRecursivePass::$processExpressions private property
AbstractRecursivePass::enableExpressionProcessing protected function
AbstractRecursivePass::getConstructor protected function
AbstractRecursivePass::getExpressionLanguage private function 1
AbstractRecursivePass::getReflectionMethod protected function
AbstractRecursivePass::inExpression protected function
AnalyzeServiceReferencesPass::$aliases private property
AnalyzeServiceReferencesPass::$byConstructor private property
AnalyzeServiceReferencesPass::$byFactory private property
AnalyzeServiceReferencesPass::$currentDefinition private property
AnalyzeServiceReferencesPass::$definitions private property
AnalyzeServiceReferencesPass::$graph private property
AnalyzeServiceReferencesPass::$lazy private property
AnalyzeServiceReferencesPass::$skipScalars protected property Overrides AbstractRecursivePass::$skipScalars
AnalyzeServiceReferencesPass::getDefinitionId private function
AnalyzeServiceReferencesPass::process public function Processes a ContainerBuilder object to populate the service reference graph. Overrides AbstractRecursivePass::process
AnalyzeServiceReferencesPass::processValue protected function Processes a value found in a definition tree. Overrides AbstractRecursivePass::processValue
AnalyzeServiceReferencesPass::__construct public function

API Navigation

  • Drupal Core 11.1.x
  • Topics
  • Classes
  • Functions
  • Constants
  • Globals
  • Files
  • Namespaces
  • Deprecated
  • Services
RSS feed
Powered by Drupal