+ private function addInlineVariables(&$head, &$tail, $id, array $arguments, $forConstructor)
+ {
+ $hasSelfRef = false;
+
+ foreach ($arguments as $argument) {
+ if (\is_array($argument)) {
+ $hasSelfRef = $this->addInlineVariables($head, $tail, $id, $argument, $forConstructor) || $hasSelfRef;
+ } elseif ($argument instanceof Reference) {
+ $hasSelfRef = $this->addInlineReference($head, $id, $this->container->normalizeId($argument), $forConstructor) || $hasSelfRef;
+ } elseif ($argument instanceof Definition) {
+ $hasSelfRef = $this->addInlineService($head, $tail, $id, $argument, $forConstructor) || $hasSelfRef;
+ }
+ }
+
+ return $hasSelfRef;
+ }
+
+ private function addInlineReference(&$code, $id, $targetId, $forConstructor)
+ {
+ $hasSelfRef = isset($this->circularReferences[$id][$targetId]);
+
+ if ('service_container' === $targetId || isset($this->referenceVariables[$targetId])) {
+ return $hasSelfRef;
+ }
+
+ list($callCount, $behavior) = $this->serviceCalls[$targetId];
+
+ if (2 > $callCount && (!$hasSelfRef || !$forConstructor)) {
+ return $hasSelfRef;
+ }
+
+ $name = $this->getNextVariableName();
+ $this->referenceVariables[$targetId] = new Variable($name);
+
+ $reference = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE >= $behavior ? new Reference($targetId, $behavior) : null;
+ $code .= sprintf(" \$%s = %s;\n", $name, $this->getServiceCall($targetId, $reference));
+
+ if (!$hasSelfRef || !$forConstructor) {
+ return $hasSelfRef;
+ }
+
+ $code .= sprintf(<<<'EOTXT'
+
+ if (isset($this->%s['%s'])) {
+ return $this->%1$s['%2$s'];
+ }
+
+EOTXT
+ ,
+ 'services',
+ $id
+ );
+
+ return false;
+ }
+
+ private function addInlineService(&$head, &$tail, $id, Definition $definition, $forConstructor)
+ {
+ if (isset($this->definitionVariables[$definition])) {
+ return false;
+ }
+
+ $arguments = array($definition->getArguments(), $definition->getFactory());
+
+ if (2 > $this->inlinedDefinitions[$definition] && !$definition->getMethodCalls() && !$definition->getProperties() && !$definition->getConfigurator()) {
+ return $this->addInlineVariables($head, $tail, $id, $arguments, $forConstructor);
+ }
+
+ $name = $this->getNextVariableName();
+ $this->definitionVariables[$definition] = new Variable($name);
+
+ $code = '';
+ if ($forConstructor) {
+ $hasSelfRef = $this->addInlineVariables($code, $tail, $id, $arguments, $forConstructor);
+ } else {
+ $hasSelfRef = $this->addInlineVariables($code, $code, $id, $arguments, $forConstructor);
+ }
+ $code .= $this->addNewInstance($definition, '$'.$name, ' = ', $id);
+ $hasSelfRef && !$forConstructor ? $tail .= ('' !== $tail ? "\n" : '').$code : $head .= ('' !== $head ? "\n" : '').$code;
+
+ $code = '';
+ $arguments = array($definition->getProperties(), $definition->getMethodCalls(), $definition->getConfigurator());
+ $hasSelfRef = $this->addInlineVariables($code, $code, $id, $arguments, false) || $hasSelfRef;
+
+ $code .= '' !== $code ? "\n" : '';
+ $code .= $this->addServiceProperties($definition, $name);
+ $code .= $this->addServiceMethodCalls($definition, $name);
+ $code .= $this->addServiceConfigurator($definition, $name);
+ if ('' !== $code) {
+ $hasSelfRef ? $tail .= ('' !== $tail ? "\n" : '').$code : $head .= $code;
+ }
+
+ return $hasSelfRef;
+ }
+