[DI] Refacto / cleanup / minor fixes

This commit is contained in:
Nicolas Grekas 2017-02-07 19:39:15 +01:00
parent a736458fb5
commit ad5b5b5d93
25 changed files with 334 additions and 270 deletions

View File

@ -162,11 +162,11 @@ class ChildDefinition extends Definition
/**
* {@inheritdoc}
*/
public function setAutowiredMethods(array $autowiredMethods)
public function setAutowiredCalls(array $autowiredCalls)
{
$this->changes['autowired_methods'] = true;
$this->changes['autowired_calls'] = true;
return parent::setAutowiredMethods($autowiredMethods);
return parent::setAutowiredCalls($autowiredCalls);
}
/**

View File

@ -24,6 +24,16 @@ use Symfony\Component\DependencyInjection\Reference;
*/
class AutowirePass extends AbstractRecursivePass
{
/**
* @internal
*/
const MODE_REQUIRED = 1;
/**
* @internal
*/
const MODE_OPTIONAL = 2;
private $definedTypes = array();
private $types;
private $ambiguousServiceTypes = array();
@ -72,7 +82,7 @@ class AutowirePass extends AbstractRecursivePass
*/
protected function processValue($value, $isRoot = false)
{
if (!$value instanceof Definition || !$autowiredMethods = $value->getAutowiredMethods()) {
if (!$value instanceof Definition || !$value->getAutowiredCalls()) {
return parent::processValue($value, $isRoot);
}
@ -80,7 +90,7 @@ class AutowirePass extends AbstractRecursivePass
return parent::processValue($value, $isRoot);
}
$autowiredMethods = $this->getMethodsToAutowire($reflectionClass, $autowiredMethods);
$autowiredMethods = $this->getMethodsToAutowire($reflectionClass, $value->getAutowiredCalls());
$methodCalls = $value->getMethodCalls();
if ($constructor = $reflectionClass->getConstructor()) {
@ -89,7 +99,7 @@ class AutowirePass extends AbstractRecursivePass
throw new RuntimeException(sprintf('Cannot autowire service "%s": class %s has no constructor but arguments are defined.', $this->currentId, $reflectionClass->name, $method));
}
$methodCalls = $this->autowireMethodCalls($reflectionClass, $methodCalls, $autowiredMethods);
$methodCalls = $this->autowireCalls($reflectionClass, $methodCalls, $autowiredMethods);
$overriddenGetters = $this->autowireOverridenGetters($value->getOverriddenGetters(), $autowiredMethods);
if ($constructor) {
@ -125,6 +135,14 @@ class AutowirePass extends AbstractRecursivePass
$regexList = array();
$methodsToAutowire = array();
if ($reflectionMethod = $reflectionClass->getConstructor()) {
$methodsToAutowire[$lcMethod = strtolower($reflectionMethod->name)] = $reflectionMethod;
unset($autowiredMethods['__construct']);
}
if (!$autowiredMethods) {
return $methodsToAutowire;
}
foreach ($autowiredMethods as $pattern) {
$regexList[] = '/^'.str_replace('\*', '.*', preg_quote($pattern, '/')).'$/i';
}
@ -141,10 +159,6 @@ class AutowirePass extends AbstractRecursivePass
continue 2;
}
}
if ($reflectionMethod->isConstructor()) {
$methodsToAutowire[strtolower($reflectionMethod->name)] = $reflectionMethod;
}
}
if ($notFound = array_diff($autowiredMethods, $found)) {
@ -161,13 +175,10 @@ class AutowirePass extends AbstractRecursivePass
*
* @return array
*/
private function autowireMethodCalls(\ReflectionClass $reflectionClass, array $methodCalls, array $autowiredMethods)
private function autowireCalls(\ReflectionClass $reflectionClass, array $methodCalls, array $autowiredMethods)
{
$parameterBag = $this->container->getParameterBag();
foreach ($methodCalls as $i => $call) {
list($method, $arguments) = $call;
$method = $parameterBag->resolveValue($method);
if (isset($autowiredMethods[$lcMethod = strtolower($method)]) && $autowiredMethods[$lcMethod]->isPublic()) {
$reflectionMethod = $autowiredMethods[$lcMethod];
@ -182,15 +193,15 @@ class AutowirePass extends AbstractRecursivePass
}
}
$arguments = $this->autowireMethodCall($reflectionMethod, $arguments, true);
$arguments = $this->autowireMethod($reflectionMethod, $arguments, self::MODE_REQUIRED);
if ($arguments !== $call[1]) {
$methodCalls[$i][1] = $arguments;
}
}
foreach ($autowiredMethods as $reflectionMethod) {
if ($reflectionMethod->isPublic() && $arguments = $this->autowireMethodCall($reflectionMethod, array(), false)) {
foreach ($autowiredMethods as $lcMethod => $reflectionMethod) {
if ($reflectionMethod->isPublic() && $arguments = $this->autowireMethod($reflectionMethod, array(), self::MODE_OPTIONAL)) {
$methodCalls[] = array($reflectionMethod->name, $arguments);
}
}
@ -203,19 +214,22 @@ class AutowirePass extends AbstractRecursivePass
*
* @param \ReflectionMethod $reflectionMethod
* @param array $arguments
* @param bool $mustAutowire
* @param int $mode
*
* @return array The autowired arguments
*
* @throws RuntimeException
*/
private function autowireMethodCall(\ReflectionMethod $reflectionMethod, array $arguments, $mustAutowire)
private function autowireMethod(\ReflectionMethod $reflectionMethod, array $arguments, $mode)
{
$didAutowire = false; // Whether any arguments have been autowired or not
foreach ($reflectionMethod->getParameters() as $index => $parameter) {
if (array_key_exists($index, $arguments) && '' !== $arguments[$index]) {
continue;
}
if (method_exists($parameter, 'isVariadic') && $parameter->isVariadic()) {
continue;
}
if (method_exists($parameter, 'getType')) {
if ($typeName = $parameter->getType()) {
@ -228,7 +242,7 @@ class AutowirePass extends AbstractRecursivePass
if (!$typeName) {
// no default value? Then fail
if (!$parameter->isOptional()) {
if ($mustAutowire) {
if (self::MODE_REQUIRED === $mode) {
throw new RuntimeException(sprintf('Cannot autowire service "%s": argument $%s of method %s::%s() must have a type-hint or be given a value explicitly.', $this->currentId, $parameter->name, $reflectionMethod->class, $reflectionMethod->name));
}
@ -268,7 +282,7 @@ class AutowirePass extends AbstractRecursivePass
$value = $parameter->getDefaultValue();
} else {
// The exception code is set to 1 if the exception must be thrown even if it's an optional setter
if (1 === $e->getCode() || $mustAutowire) {
if (1 === $e->getCode() || self::MODE_REQUIRED === $mode) {
throw $e;
}
@ -279,7 +293,7 @@ class AutowirePass extends AbstractRecursivePass
// Typehint against a non-existing class
if (!$parameter->isDefaultValueAvailable()) {
if ($mustAutowire) {
if (self::MODE_REQUIRED === $mode) {
throw new RuntimeException(sprintf('Cannot autowire argument $%s of method %s::%s() for service "%s": Class %s does not exist.', $parameter->name, $reflectionMethod->class, $reflectionMethod->name, $this->currentId, $typeName));
}
@ -292,7 +306,7 @@ class AutowirePass extends AbstractRecursivePass
$arguments[$index] = $value;
}
if (!$mustAutowire && !$didAutowire) {
if (self::MODE_REQUIRED !== $mode && !$didAutowire) {
return array();
}
@ -313,8 +327,8 @@ class AutowirePass extends AbstractRecursivePass
*/
private function autowireOverridenGetters(array $overridenGetters, array $autowiredMethods)
{
foreach ($autowiredMethods as $reflectionMethod) {
if (isset($overridenGetters[strtolower($reflectionMethod->name)])
foreach ($autowiredMethods as $lcMethod => $reflectionMethod) {
if (isset($overridenGetters[$lcMethod])
|| !method_exists($reflectionMethod, 'getReturnType')
|| 0 !== $reflectionMethod->getNumberOfParameters()
|| $reflectionMethod->isFinal()
@ -326,7 +340,7 @@ class AutowirePass extends AbstractRecursivePass
$typeName = $returnType instanceof \ReflectionNamedType ? $returnType->getName() : $returnType->__toString();
if ($this->container->has($typeName) && !$this->container->findDefinition($typeName)->isAbstract()) {
$overridenGetters[$reflectionMethod->name] = new Reference($typeName);
$overridenGetters[$lcMethod] = new Reference($typeName);
continue;
}
@ -346,7 +360,7 @@ class AutowirePass extends AbstractRecursivePass
continue;
}
$overridenGetters[$reflectionMethod->name] = $value;
$overridenGetters[$lcMethod] = $value;
}
return $overridenGetters;

View File

@ -101,7 +101,7 @@ class ResolveDefinitionTemplatesPass extends AbstractRecursivePass
$def->setFile($parentDef->getFile());
$def->setPublic($parentDef->isPublic());
$def->setLazy($parentDef->isLazy());
$def->setAutowiredMethods($parentDef->getAutowiredMethods());
$def->setAutowiredCalls($parentDef->getAutowiredCalls());
// overwrite with values specified in the decorator
$changes = $definition->getChanges();
@ -126,8 +126,8 @@ class ResolveDefinitionTemplatesPass extends AbstractRecursivePass
if (isset($changes['deprecated'])) {
$def->setDeprecated($definition->isDeprecated(), $definition->getDeprecationMessage('%service_id%'));
}
if (isset($changes['autowired_methods'])) {
$def->setAutowiredMethods($definition->getAutowiredMethods());
if (isset($changes['autowired_calls'])) {
$def->setAutowiredCalls($definition->getAutowiredCalls());
}
if (isset($changes['decorated_service'])) {
$decoratedService = $definition->getDecoratedService();

View File

@ -33,7 +33,8 @@ use Symfony\Component\Config\Resource\ReflectionClassResource;
use Symfony\Component\Config\Resource\ResourceInterface;
use Symfony\Component\DependencyInjection\LazyProxy\Instantiator\InstantiatorInterface;
use Symfony\Component\DependencyInjection\LazyProxy\Instantiator\RealServiceInstantiator;
use Symfony\Component\DependencyInjection\LazyProxy\GetterProxyInterface;
use Symfony\Component\DependencyInjection\LazyProxy\InheritanceProxyHelper;
use Symfony\Component\DependencyInjection\LazyProxy\InheritanceProxyInterface;
use Symfony\Component\ExpressionLanguage\Expression;
use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;
@ -1022,7 +1023,7 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
if (null === $salt) {
$salt = str_replace('.', '', uniqid('', true));
}
$service = sprintf('%s implements \\%s { private $container%4$s; private $values%4$s; %s }', $r->name, GetterProxyInterface::class, $this->generateOverriddenGetters($id, $definition, $r, $salt), $salt);
$service = sprintf('%s implements \\%s { private $container%4$s; private $getters%4$s; %s }', $r->name, InheritanceProxyInterface::class, $this->generateOverriddenMethods($id, $definition, $r, $salt), $salt);
if (!class_exists($proxyClass = 'SymfonyProxy_'.md5($service), false)) {
eval(sprintf('class %s extends %s', $proxyClass, $service));
}
@ -1032,7 +1033,7 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
$constructor = null;
}
$service = $constructor ? $r->newInstanceWithoutConstructor() : $r->newInstanceArgs($arguments);
call_user_func(\Closure::bind(function ($c, $v, $s) { $this->{'container'.$s} = $c; $this->{'values'.$s} = $v; }, $service, $service), $this, $definition->getOverriddenGetters(), $salt);
call_user_func(\Closure::bind(function ($c, $g, $s) { $this->{'container'.$s} = $c; $this->{'getters'.$s} = $g; }, $service, $service), $this, $definition->getOverriddenGetters(), $salt);
if ($constructor) {
$constructor->invokeArgs($service, $arguments);
}
@ -1294,22 +1295,29 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
return $this->envCounters;
}
private function generateOverriddenGetters($id, Definition $definition, \ReflectionClass $class, $salt)
private function generateOverriddenMethods($id, Definition $definition, \ReflectionClass $class, $salt)
{
if ($class->isFinal()) {
throw new RuntimeException(sprintf('Unable to configure getter injection for service "%s": class "%s" cannot be marked as final.', $id, $class->name));
throw new RuntimeException(sprintf('Unable to configure service "%s": class "%s" cannot be marked as final.', $id, $class->name));
}
return $this->generateOverriddenGetters($id, $definition, $class, $salt);
}
private function generateOverriddenGetters($id, Definition $definition, \ReflectionClass $class, $salt)
{
$getters = '';
foreach ($definition->getOverriddenGetters() as $name => $returnValue) {
$r = self::getGetterReflector($class, $name, $id, $type);
$r = InheritanceProxyHelper::getGetterReflector($class, $name, $id);
$signature = InheritanceProxyHelper::getSignature($r);
$visibility = $r->isProtected() ? 'protected' : 'public';
$name = var_export($name, true);
$getters .= <<<EOF
{$visibility} function {$r->name}(){$type} {
{$visibility} function {$signature} {
\$c = \$this->container{$salt};
\$b = \$c->getParameterBag();
\$v = \$this->values{$salt}[{$name}];
\$v = \$this->getters{$salt}['{$name}'];
foreach (\$c->getServiceConditionals(\$v) as \$s) {
if (!\$c->has(\$s)) {
@ -1325,71 +1333,6 @@ EOF;
return $getters;
}
/**
* @internal
*/
public static function getGetterReflector(\ReflectionClass $class, $name, $id, &$type)
{
if (!$class->hasMethod($name)) {
throw new RuntimeException(sprintf('Unable to configure getter injection for service "%s": method "%s::%s" does not exist.', $id, $class->name, $name));
}
$r = $class->getMethod($name);
if ($r->isPrivate()) {
throw new RuntimeException(sprintf('Unable to configure getter injection for service "%s": method "%s::%s" must be public or protected.', $id, $class->name, $r->name));
}
if ($r->isStatic()) {
throw new RuntimeException(sprintf('Unable to configure getter injection for service "%s": method "%s::%s" cannot be static.', $id, $class->name, $r->name));
}
if ($r->isFinal()) {
throw new RuntimeException(sprintf('Unable to configure getter injection for service "%s": method "%s::%s" cannot be marked as final.', $id, $class->name, $r->name));
}
if ($r->returnsReference()) {
throw new RuntimeException(sprintf('Unable to configure getter injection for service "%s": method "%s::%s" cannot return by reference.', $id, $class->name, $r->name));
}
if (0 < $r->getNumberOfParameters()) {
throw new RuntimeException(sprintf('Unable to configure getter injection for service "%s": method "%s::%s" cannot have any arguments.', $id, $class->name, $r->name));
}
if ($type = method_exists($r, 'getReturnType') ? $r->getReturnType() : null) {
$type = ': '.($type->allowsNull() ? '?' : '').self::generateTypeHint($type, $r);
}
return $r;
}
/**
* @internal
*/
public static function generateTypeHint($type, \ReflectionFunctionAbstract $r)
{
if (is_string($type)) {
$name = $type;
if ('callable' === $name || 'array' === $name) {
return $name;
}
} else {
$name = $type instanceof \ReflectionNamedType ? $type->getName() : $type->__toString();
if ($type->isBuiltin()) {
return $name;
}
}
$lcName = strtolower($name);
if ('self' !== $lcName && 'parent' !== $lcName) {
return '\\'.$name;
}
if (!$r instanceof \ReflectionMethod) {
return;
}
if ('self' === $lcName) {
return '\\'.$r->getDeclaringClass()->name;
}
if ($parent = $r->getDeclaringClass()->getParentClass()) {
return '\\'.$parent->name;
}
}
/**
* @internal
*/

View File

@ -37,7 +37,7 @@ class Definition
private $abstract = false;
private $lazy = false;
private $decoratedService;
private $autowiredMethods = array();
private $autowiredCalls = array();
private $autowiringTypes = array();
protected $arguments;
@ -325,6 +325,8 @@ class Definition
}
/**
* @return $this
*
* @experimental in version 3.3
*/
public function setOverriddenGetter($name, $returnValue)
@ -338,6 +340,8 @@ class Definition
}
/**
* @return $this
*
* @experimental in version 3.3
*/
public function setOverriddenGetters(array $getters)
@ -702,7 +706,7 @@ class Definition
*/
public function isAutowired()
{
return !empty($this->autowiredMethods);
return !empty($this->autowiredCalls);
}
/**
@ -710,17 +714,17 @@ class Definition
*
* @return string[]
*/
public function getAutowiredMethods()
public function getAutowiredCalls()
{
return $this->autowiredMethods;
return $this->autowiredCalls;
}
/**
* Sets autowired.
*
* Allowed values:
* - true: constructor autowiring, same as $this->setAutowiredMethods(array('__construct'))
* - false: no autowiring, same as $this->setAutowiredMethods(array())
* - true: constructor autowiring, same as $this->setAutowiredCalls(array('__construct'))
* - false: no autowiring, same as $this->setAutowiredCalls(array())
*
* @param bool $autowired
*
@ -728,7 +732,7 @@ class Definition
*/
public function setAutowired($autowired)
{
$this->autowiredMethods = $autowired ? array('__construct') : array();
$this->autowiredCalls = $autowired ? array('__construct') : array();
return $this;
}
@ -739,13 +743,13 @@ class Definition
* Example of allowed value:
* - array('__construct', 'set*', 'initialize'): autowire whitelisted methods only
*
* @param string[] $autowiredMethods
* @param string[] $autowiredCalls
*
* @return Definition The current instance
* @return $this
*/
public function setAutowiredMethods(array $autowiredMethods)
public function setAutowiredCalls(array $autowiredCalls)
{
$this->autowiredMethods = $autowiredMethods;
$this->autowiredCalls = $autowiredCalls;
return $this;
}

View File

@ -24,7 +24,8 @@ use Symfony\Component\DependencyInjection\Exception\EnvParameterException;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
use Symfony\Component\DependencyInjection\LazyProxy\GetterProxyInterface;
use Symfony\Component\DependencyInjection\LazyProxy\InheritanceProxyHelper;
use Symfony\Component\DependencyInjection\LazyProxy\InheritanceProxyInterface;
use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface as ProxyDumper;
use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\NullDumper;
use Symfony\Component\DependencyInjection\ExpressionLanguage;
@ -65,7 +66,7 @@ class PhpDumper extends Dumper
private $serviceIdToMethodNameMap;
private $usedMethodNames;
private $baseClass;
private $getterProxies = array();
private $inheritanceProxies = array();
private $useInstantiateProxy;
private $salt;
@ -124,7 +125,7 @@ class PhpDumper extends Dumper
), $options);
$this->salt = substr(strtr(base64_encode(md5($options['namespace'].'\\'.$options['class'].'+'.$options['base_class'], true)), '+/', '__'), 0, -2);
$this->getterProxies = array();
$this->inheritanceProxies = array();
$this->useInstantiateProxy = false;
$this->initializeMethodNamesMap($options['base_class']);
$this->baseClass = $options['base_class'];
@ -173,7 +174,7 @@ class PhpDumper extends Dumper
$this->addProxyClasses()
;
$this->targetDirRegex = null;
$this->getterProxies = array();
$this->inheritanceProxies = array();
$unusedEnvs = array();
foreach ($this->container->getEnvCounters() as $env => $use) {
@ -277,7 +278,7 @@ class PhpDumper extends Dumper
$code .= $proxyCode;
}
foreach ($this->getterProxies as $proxyClass => $proxyCode) {
foreach ($this->inheritanceProxies as $proxyClass => $proxyCode) {
$code .= sprintf("\nclass %s extends %s", $proxyClass, $proxyCode);
}
@ -494,11 +495,11 @@ class PhpDumper extends Dumper
return $calls;
}
private function addServiceOverriddenGetters($id, Definition $definition)
private function addServiceOverriddenMethods($id, Definition $definition)
{
$class = $this->container->getReflectionClass($definition->getClass());
if ($class->isFinal()) {
throw new RuntimeException(sprintf('Unable to configure getter injection for service "%s": class "%s" cannot be marked as final.', $id, $class->name));
throw new RuntimeException(sprintf('Unable to configure service "%s": class "%s" cannot be marked as final.', $id, $class->name));
}
if ($r = $class->getConstructor()) {
@ -510,22 +511,31 @@ class PhpDumper extends Dumper
}
if (!$r->isFinal()) {
if (0 < $r->getNumberOfParameters()) {
$getters = implode('__construct($container'.$this->salt.', ', explode('(', $this->generateSignature($r), 2));
$constructor = implode('($container'.$this->salt.', ', explode('(', InheritanceProxyHelper::getSignature($r, $call), 2));
} else {
$getters = '__construct($container'.$this->salt.')';
$constructor = $r->name.'($container'.$this->salt.')';
$call = $r->name.'()';
}
$getters = sprintf("\n public function %s\n {\n \$this->container%3\$s = \$container%3\$s;\n parent::%s;\n }\n", $getters, $this->generateCall($r), $this->salt);
$constructor = sprintf("\n public function %s\n {\n \$this->container%3\$s = \$container%3\$s;\n parent::%s;\n }\n", $constructor, $call, $this->salt);
} else {
$getters = '';
$constructor = '';
}
} else {
$getters = sprintf("\n public function __construct(\$container%1\$s)\n {\n \$this->container%1\$s = \$container%1\$s;\n }\n", $this->salt);
$constructor = sprintf("\n public function __construct(\$container%1\$s)\n {\n \$this->container%1\$s = \$container%1\$s;\n }\n", $this->salt);
}
return $constructor.$this->addServiceOverriddenGetters($id, $definition, $class);
}
private function addServiceOverriddenGetters($id, Definition $definition, \ReflectionClass $class)
{
$getters = '';
foreach ($definition->getOverriddenGetters() as $name => $returnValue) {
$r = ContainerBuilder::getGetterReflector($class, $name, $id, $type);
$r = InheritanceProxyHelper::getGetterReflector($class, $name, $id);
$getter = array();
$getter[] = sprintf('%s function %s()%s', $r->isProtected() ? 'protected' : 'public', $r->name, $type);
$getter[] = sprintf('%s function %s', $r->isProtected() ? 'protected' : 'public', InheritanceProxyHelper::getSignature($r));
$getter[] = '{';
if (false === strpos($dumpedReturnValue = $this->dumpValue($returnValue), '$this')) {
@ -846,9 +856,10 @@ EOF;
$class = $this->dumpLiteralClass($class);
if ($definition->getOverriddenGetters()) {
$getterProxy = sprintf("%s implements \\%s\n{\n private \$container%s;\n private \$getters%3\$s;\n%s}\n", $class, GetterProxyInterface::class, $this->salt, $this->addServiceOverriddenGetters($id, $definition));
$class = 'SymfonyProxy_'.md5($getterProxy);
$this->getterProxies[$class] = $getterProxy;
$inheritanceProxy = " private \$container{$this->salt};\n private \$getters{$this->salt};\n";
$inheritanceProxy = sprintf("%s implements \\%s\n{\n%s%s}\n", $class, InheritanceProxyInterface::class, $inheritanceProxy, $this->addServiceOverriddenMethods($id, $definition));
$class = 'SymfonyProxy_'.md5($inheritanceProxy);
$this->inheritanceProxies[$class] = $inheritanceProxy;
$constructor = $this->container->getReflectionClass($definition->getClass())->getConstructor();
if ($constructor && $constructor->isFinal()) {
@ -1622,8 +1633,9 @@ EOF;
if (!$r->isPublic()) {
throw new InvalidArgumentException(sprintf('Cannot create closure-proxy for service "%s": method "%s::%s" must be public.', $reference, $class, $method));
}
$signature = preg_replace('/^(&?)[^(]*/', '$1', InheritanceProxyHelper::getSignature($r, $call));
return sprintf("/** @closure-proxy %s::%s */ function %s {\n return %s->%s;\n }", $class, $method, $this->generateSignature($r), $this->dumpValue($reference), $this->generateCall($r));
return sprintf("/** @closure-proxy %s::%s */ function %s {\n return %s->%s;\n }", $class, $method, $signature, $this->dumpValue($reference), $call);
} elseif ($value instanceof Variable) {
return '$'.$value;
} elseif ($value instanceof Reference) {
@ -1883,62 +1895,4 @@ EOF;
return $export;
}
private function generateSignature(\ReflectionFunctionAbstract $r)
{
$signature = array();
foreach ($r->getParameters() as $p) {
$k = '$'.$p->name;
if (method_exists($p, 'isVariadic') && $p->isVariadic()) {
$k = '...'.$k;
}
if ($p->isPassedByReference()) {
$k = '&'.$k;
}
if (method_exists($p, 'getType')) {
$type = $p->getType();
} elseif (preg_match('/^(?:[^ ]++ ){4}([a-zA-Z_\x7F-\xFF][^ ]++)/', $p, $type)) {
$type = $type[1];
}
if ($type && $type = ContainerBuilder::generateTypeHint($type, $r)) {
$k = $type.' '.$k;
}
if ($type && $p->allowsNull()) {
$k = '?'.$k;
}
try {
$k .= ' = '.$this->dumpValue($p->getDefaultValue(), false);
if ($type && $p->allowsNull() && null === $p->getDefaultValue()) {
$k = substr($k, 1);
}
} catch (\ReflectionException $e) {
if ($type && $p->allowsNull() && !class_exists('ReflectionNamedType', false)) {
$k .= ' = null';
$k = substr($k, 1);
}
}
$signature[] = $k;
}
return ($r->returnsReference() ? '&(' : '(').implode(', ', $signature).')';
}
private function generateCall(\ReflectionFunctionAbstract $r)
{
$call = array();
foreach ($r->getParameters() as $p) {
$k = '$'.$p->name;
if (method_exists($p, 'isVariadic') && $p->isVariadic()) {
$k = '...'.$k;
}
$call[] = $k;
}
return ($r->isClosure() ? '' : $r->name).'('.implode(', ', $call).')';
}
}

View File

@ -0,0 +1,149 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\DependencyInjection\LazyProxy;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
/**
* @author Nicolas Grekas <p@tchwork.com>
*
* @internal
*/
class InheritanceProxyHelper
{
public static function getGetterReflector(\ReflectionClass $class, $name, $id)
{
if (!$class->hasMethod($name)) {
throw new RuntimeException(sprintf('Unable to configure getter injection for service "%s": method "%s::%s" does not exist.', $id, $class->name, $name));
}
$r = $class->getMethod($name);
if ($r->isPrivate()) {
throw new RuntimeException(sprintf('Unable to configure getter injection for service "%s": method "%s::%s" must be public or protected.', $id, $class->name, $r->name));
}
if ($r->isStatic()) {
throw new RuntimeException(sprintf('Unable to configure getter injection for service "%s": method "%s::%s" cannot be static.', $id, $class->name, $r->name));
}
if ($r->isFinal()) {
throw new RuntimeException(sprintf('Unable to configure getter injection for service "%s": method "%s::%s" cannot be marked as final.', $id, $class->name, $r->name));
}
if ($r->returnsReference()) {
throw new RuntimeException(sprintf('Unable to configure getter injection for service "%s": method "%s::%s" cannot return by reference.', $id, $class->name, $r->name));
}
if (0 < $r->getNumberOfParameters()) {
throw new RuntimeException(sprintf('Unable to configure getter injection for service "%s": method "%s::%s" cannot have any arguments.', $id, $class->name, $r->name));
}
return $r;
}
/**
* @return string The signature of the passed function, return type and function/method name included if any
*/
public static function getSignature(\ReflectionFunctionAbstract $r, &$call = null)
{
$signature = array();
$call = array();
foreach ($r->getParameters() as $i => $p) {
$k = '$'.$p->name;
if (method_exists($p, 'isVariadic') && $p->isVariadic()) {
$k = '...'.$k;
}
$call[] = $k;
if ($p->isPassedByReference()) {
$k = '&'.$k;
}
if (method_exists($p, 'getType')) {
$type = $p->getType();
} elseif (preg_match('/^(?:[^ ]++ ){4}([a-zA-Z_\x7F-\xFF][^ ]++)/', $p, $type)) {
$type = $type[1];
}
if ($type && $type = self::getTypeHint($type, $r)) {
$k = $type.' '.$k;
}
if ($type && $p->allowsNull()) {
$k = '?'.$k;
}
try {
$k .= ' = '.self::export($p->getDefaultValue());
if ($type && $p->allowsNull() && null === $p->getDefaultValue()) {
$k = substr($k, 1);
}
} catch (\ReflectionException $e) {
if ($type && $p->allowsNull() && !class_exists('ReflectionNamedType', false)) {
$k .= ' = null';
$k = substr($k, 1);
}
}
$signature[] = $k;
}
$call = ($r->isClosure() ? '' : $r->name).'('.implode(', ', $call).')';
if ($type = method_exists($r, 'getReturnType') ? $r->getReturnType() : null) {
$type = ': '.($type->allowsNull() ? '?' : '').self::getTypeHint($type, $r);
}
return ($r->returnsReference() ? '&' : '').($r->isClosure() ? '' : $r->name).'('.implode(', ', $signature).')'.$type;
}
/**
* @param $type \ReflectionType|string $type As returned by ReflectionParameter::getType() - or string on PHP 5
*
* @return string|null The FQCN or builtin name of the type hint, or null when the type hint references an invalid self|parent context
*/
public static function getTypeHint($type, \ReflectionFunctionAbstract $r)
{
if (is_string($type)) {
$name = $type;
if ('callable' === $name || 'array' === $name) {
return $name;
}
} else {
$name = $type instanceof \ReflectionNamedType ? $type->getName() : $type->__toString();
if ($type->isBuiltin()) {
return $name;
}
}
$lcName = strtolower($name);
if ('self' !== $lcName && 'parent' !== $lcName) {
return '\\'.$name;
}
if (!$r instanceof \ReflectionMethod) {
return;
}
if ('self' === $lcName) {
return '\\'.$r->getDeclaringClass()->name;
}
if ($parent = $r->getDeclaringClass()->getParentClass()) {
return '\\'.$parent->name;
}
}
private static function export($value)
{
if (!is_array($value)) {
return var_export($value, true);
}
$code = array();
foreach ($value as $k => $v) {
$code[] = sprintf('%s => %s', var_export($k, true), self::export($v));
}
return sprintf('array(%s)', implode(', ', $code));
}
}

View File

@ -12,12 +12,12 @@
namespace Symfony\Component\DependencyInjection\LazyProxy;
/**
* Interface used to label proxy classes with overridden getters as generated while compiling the container.
* Interface used to label proxy classes with overridden methods as generated while compiling the container.
*
* @author Nicolas Grekas <p@tchwork.com>
*
* @experimental in version 3.3
*/
interface GetterProxyInterface
interface InheritanceProxyInterface
{
}

View File

@ -242,7 +242,7 @@ class XmlFileLoader extends FileLoader
$definition->setDeprecated(true, $deprecated[0]->nodeValue ?: null);
}
$definition->setArguments($this->getArgumentsAsPhp($service, 'argument'));
$definition->setArguments($this->getArgumentsAsPhp($service, 'argument', false, (bool) $parent));
$definition->setProperties($this->getArgumentsAsPhp($service, 'property'));
$definition->setOverriddenGetters($this->getArgumentsAsPhp($service, 'getter'));
@ -325,19 +325,19 @@ class XmlFileLoader extends FileLoader
$definition->addAutowiringType($type->textContent);
}
$autowireTags = array();
foreach ($this->getChildren($service, 'autowire') as $type) {
$autowireTags[] = $type->textContent;
$autowiredCalls = array();
foreach ($this->getChildren($service, 'autowire') as $tag) {
$autowiredCalls[] = $tag->textContent;
}
if ($autowireTags) {
if ($service->hasAttribute('autowire')) {
throw new InvalidArgumentException(sprintf('The "autowire" attribute cannot be used together with "<autowire>" tags for service "%s" in %s.', (string) $service->getAttribute('id'), $file));
}
if ($autowiredCalls && $service->hasAttribute('autowire')) {
throw new InvalidArgumentException(sprintf('The "autowire" attribute cannot be used together with "<autowire>" tags for service "%s" in %s.', $service->getAttribute('id'), $file));
}
$definition->setAutowiredMethods($autowireTags);
if ($autowiredCalls) {
$definition->setAutowiredCalls($autowiredCalls);
} elseif (!$service->hasAttribute('autowire') && !empty($defaults['autowire'])) {
$definition->setAutowiredMethods($defaults['autowire']);
$definition->setAutowiredCalls($defaults['autowire']);
}
if ($value = $service->getAttribute('decorates')) {
@ -439,7 +439,7 @@ class XmlFileLoader extends FileLoader
*
* @return mixed
*/
private function getArgumentsAsPhp(\DOMElement $node, $name, $lowercase = true)
private function getArgumentsAsPhp(\DOMElement $node, $name, $lowercase = true, $isChildDefinition = false)
{
$arguments = array();
foreach ($this->getChildren($node, $name) as $arg) {
@ -450,7 +450,7 @@ class XmlFileLoader extends FileLoader
// this is used by ChildDefinition to overwrite a specific
// argument of the parent definition
if ($arg->hasAttribute('index')) {
$key = 'index_'.$arg->getAttribute('index');
$key = ($isChildDefinition ? 'index_' : '').$arg->getAttribute('index');
} elseif (!$arg->hasAttribute('key')) {
// Append an empty argument, then fetch its key to overwrite it later
$arguments[] = null;

View File

@ -406,12 +406,22 @@ class YamlFileLoader extends FileLoader
}
$autowire = isset($service['autowire']) ? $service['autowire'] : (isset($defaults['autowire']) ? $defaults['autowire'] : null);
if (null !== $autowire) {
if (is_array($autowire)) {
$definition->setAutowiredMethods($autowire);
} else {
$definition->setAutowired($autowire);
if (is_array($autowire)) {
$autowiredCalls = array();
foreach ($autowire as $v) {
if (is_string($v)) {
$autowiredCalls[] = $v;
} else {
throw new InvalidArgumentException(sprintf('Parameter "autowire" must be boolean or string[] for service "%s" in %s. Check your YAML syntax.', $id, $file));
}
}
if ($autowiredCalls) {
$definition->setAutowiredCalls($autowiredCalls);
}
} elseif (null !== $autowire) {
$definition->setAutowired($autowire);
}
if (isset($service['autowiring_types'])) {

View File

@ -70,14 +70,14 @@ class ChildDefinitionTest extends \PHPUnit_Framework_TestCase
$this->assertSame(array('lazy' => true), $def->getChanges());
}
public function testSetAutowiredMethods()
public function testSetAutowiredCalls()
{
$def = new ChildDefinition('foo');
$this->assertFalse($def->isAutowired());
$this->assertSame($def, $def->setAutowiredMethods(array('foo', 'bar')));
$this->assertEquals(array('foo', 'bar'), $def->getAutowiredMethods());
$this->assertSame(array('autowired_methods' => true), $def->getChanges());
$this->assertSame($def, $def->setAutowiredCalls(array('foo', 'bar')));
$this->assertEquals(array('foo', 'bar'), $def->getAutowiredCalls());
$this->assertSame(array('autowired_calls' => true), $def->getChanges());
}
public function testSetArgument()

View File

@ -460,7 +460,7 @@ class AutowirePassTest extends \PHPUnit_Framework_TestCase
// manually configure *one* call, to override autowiring
$container
->register('setter_injection', SetterInjection::class)
->setAutowiredMethods(array('set*'))
->setAutowiredCalls(array('set*'))
->addMethodCall('setWithCallsConfigured', array('manual_arg1', 'manual_arg2'))
;
@ -500,7 +500,7 @@ class AutowirePassTest extends \PHPUnit_Framework_TestCase
$container
->register('setter_injection', SetterInjection::class)
->setAutowiredMethods(array('setFoo', 'notASetter'))
->setAutowiredCalls(array('setFoo', 'notASetter'))
;
$pass = new AutowirePass();
@ -528,7 +528,7 @@ class AutowirePassTest extends \PHPUnit_Framework_TestCase
$container
->register('getter_overriding', GetterOverriding::class)
->setOverriddenGetter('getExplicitlyDefined', new Reference('b'))
->setAutowiredMethods(array('get*'))
->setAutowiredCalls(array('get*'))
;
$pass = new AutowirePass();
@ -603,7 +603,7 @@ class AutowirePassTest extends \PHPUnit_Framework_TestCase
$container->register('c1', CollisionA::class);
$container->register('c2', CollisionB::class);
$aDefinition = $container->register('setter_injection_collision', SetterInjectionCollision::class);
$aDefinition->setAutowiredMethods(array('set*'));
$aDefinition->setAutowiredCalls(array('set*'));
$pass = new AutowirePass();
$pass->process($container);
@ -614,7 +614,7 @@ class AutowirePassTest extends \PHPUnit_Framework_TestCase
$container = new ContainerBuilder();
$definition = $container->register('foo', Foo::class);
$definition->setAutowiredMethods(array('not', 'exist*'));
$definition->setAutowiredCalls(array('not', 'exist*'));
$pass = new AutowirePass();
$pass->process($container);
@ -622,17 +622,6 @@ class AutowirePassTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(array(AutowirePass::class.': Autowiring\'s patterns "not", "exist*" for service "foo" don\'t match any method.'), $container->getCompiler()->getLog());
}
public function testPartialMethodCalls()
{
$container = new ContainerBuilder();
$container->register('a', A::class);
$container->register('foo', Foo::class);
$definition = $container->register('bar', SetterInjection::class);
$definition->setAutowired(true);
$definition->addMethodCall('setDependencies', array(new Reference('foo')));
}
public function testEmptyStringIsKept()
{
$container = new ContainerBuilder();

View File

@ -215,15 +215,16 @@ class ResolveDefinitionTemplatesPassTest extends \PHPUnit_Framework_TestCase
$container = new ContainerBuilder();
$container->register('parent', 'stdClass')
->setAutowiredMethods(array('foo', 'bar'));
->setAutowiredCalls(array('foo'))
;
$container->setDefinition('child1', new ChildDefinition('parent'))
->setAutowiredMethods(array('baz'))
->setAutowiredCalls(array('baz'))
;
$this->process($container);
$this->assertEquals(array('baz'), $container->getDefinition('child1')->getAutowiredMethods());
$this->assertEquals(array('baz'), $container->getDefinition('child1')->getAutowiredCalls());
}
public function testSetAutowiredOnServiceIsParent()
@ -231,14 +232,14 @@ class ResolveDefinitionTemplatesPassTest extends \PHPUnit_Framework_TestCase
$container = new ContainerBuilder();
$container->register('parent', 'stdClass')
->setAutowiredMethods(array('__construct', 'set*'))
->setAutowiredCalls(array('__construct', 'set*'))
;
$container->setDefinition('child1', new ChildDefinition('parent'));
$this->process($container);
$this->assertEquals(array('__construct', 'set*'), $container->getDefinition('child1')->getAutowiredMethods());
$this->assertEquals(array('__construct', 'set*'), $container->getDefinition('child1')->getAutowiredCalls());
}
public function testDeepDefinitionsResolving()

View File

@ -895,7 +895,7 @@ class ContainerBuilderTest extends \PHPUnit_Framework_TestCase
yield array('Unable to configure getter injection for service "foo": method "Symfony\Component\DependencyInjection\Tests\Fixtures\Container30\Foo::getFinal" cannot be marked as final.', 'getFinal');
yield array('Unable to configure getter injection for service "foo": method "Symfony\Component\DependencyInjection\Tests\Fixtures\Container30\Foo::getRef" cannot return by reference.', 'getRef');
yield array('Unable to configure getter injection for service "foo": method "Symfony\Component\DependencyInjection\Tests\Fixtures\Container30\Foo::getParam" cannot have any arguments.', 'getParam');
yield array('Unable to configure getter injection for service "bar": class "Symfony\Component\DependencyInjection\Tests\Fixtures\Container30\Bar" cannot be marked as final.', 'getParam', 'bar');
yield array('Unable to configure service "bar": class "Symfony\Component\DependencyInjection\Tests\Fixtures\Container30\Bar" cannot be marked as final.', 'getParam', 'bar');
yield array('Cannot create service "baz": factories and overridden getters are incompatible with each other.', 'getParam', 'baz');
}

View File

@ -72,14 +72,14 @@ class DefinitionDecoratorTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(array('lazy' => true), $def->getChanges());
}
public function testSetAutowiredMethods()
public function testSetAutowiredCalls()
{
$def = new DefinitionDecorator('foo');
$this->assertFalse($def->isAutowired());
$this->assertSame($def, $def->setAutowiredMethods(array('foo', 'bar')));
$this->assertEquals(array('foo', 'bar'), $def->getAutowiredMethods());
$this->assertEquals(array('autowired_methods' => true), $def->getChanges());
$this->assertSame($def, $def->setAutowiredCalls(array('foo', 'bar')));
$this->assertEquals(array('foo', 'bar'), $def->getAutowiredCalls());
$this->assertEquals(array('autowired_calls' => true), $def->getChanges());
}
public function testSetArgument()

View File

@ -301,15 +301,15 @@ class DefinitionTest extends \PHPUnit_Framework_TestCase
$this->assertFalse($def->isAutowired());
$def->setAutowired(true);
$this->assertTrue($def->isAutowired());
$this->assertEquals(array('__construct'), $def->getAutowiredMethods());
$this->assertEquals(array('__construct'), $def->getAutowiredCalls());
$def->setAutowiredMethods(array('foo'));
$def->setAutowiredCalls(array('foo'));
$def->setAutowired(false);
$this->assertSame(array(), $def->getAutowiredMethods());
$this->assertSame(array(), $def->getAutowiredCalls());
$this->assertFalse($def->isAutowired());
$def->setAutowiredMethods(array('getFoo', 'getBar'));
$this->assertEquals(array('getFoo', 'getBar'), $def->getAutowiredMethods());
$def->setAutowiredCalls(array('getFoo', 'getBar'));
$this->assertEquals(array('getFoo', 'getBar'), $def->getAutowiredCalls());
$this->assertTrue($def->isAutowired());
}

View File

@ -389,7 +389,7 @@ class PhpDumperTest extends \PHPUnit_Framework_TestCase
yield array('Unable to configure getter injection for service "foo": method "Symfony\Component\DependencyInjection\Tests\Fixtures\Container30\Foo::getFinal" cannot be marked as final.', 'getFinal');
yield array('Unable to configure getter injection for service "foo": method "Symfony\Component\DependencyInjection\Tests\Fixtures\Container30\Foo::getRef" cannot return by reference.', 'getRef');
yield array('Unable to configure getter injection for service "foo": method "Symfony\Component\DependencyInjection\Tests\Fixtures\Container30\Foo::getParam" cannot have any arguments.', 'getParam');
yield array('Unable to configure getter injection for service "bar": class "Symfony\Component\DependencyInjection\Tests\Fixtures\Container30\Bar" cannot be marked as final.', 'getParam', 'bar');
yield array('Unable to configure service "bar": class "Symfony\Component\DependencyInjection\Tests\Fixtures\Container30\Bar" cannot be marked as final.', 'getParam', 'bar');
yield array('Cannot dump definition for service "baz": factories and overridden getters are incompatible with each other.', 'getParam', 'baz');
}

View File

@ -61,7 +61,7 @@ class Symfony_DI_PhpDumper_Test_Overriden_Getters extends Container
*/
protected function getBazService()
{
return $this->services['baz'] = $this->instantiateProxy(SymfonyProxy_46eafd3003c2798ed583593e686cb95e::class, array(), true);
return $this->services['baz'] = $this->instantiateProxy(SymfonyProxy_1e2f71108c6e0938cdbc9e38cae3dcb5::class, array(), true);
}
/**
@ -74,7 +74,7 @@ class Symfony_DI_PhpDumper_Test_Overriden_Getters extends Container
*/
protected function getFooService()
{
return $this->services['foo'] = new SymfonyProxy_78f39120a5353f811849a5b3f3e6d70c($this);
return $this->services['foo'] = new SymfonyProxy_4a8df73e139322e3fa994cdec2f5b203($this);
}
private function instantiateProxy($class, $args, $useConstructor)
@ -97,7 +97,7 @@ class Symfony_DI_PhpDumper_Test_Overriden_Getters extends Container
}
}
class SymfonyProxy_46eafd3003c2798ed583593e686cb95e extends \Symfony\Component\DependencyInjection\Tests\Fixtures\Container29\Baz implements \Symfony\Component\DependencyInjection\LazyProxy\GetterProxyInterface
class SymfonyProxy_1e2f71108c6e0938cdbc9e38cae3dcb5 extends \Symfony\Component\DependencyInjection\Tests\Fixtures\Container29\Baz implements \Symfony\Component\DependencyInjection\LazyProxy\InheritanceProxyInterface
{
private $container6HqvH3fsTTC6dr66HyT2Jw;
private $getters6HqvH3fsTTC6dr66HyT2Jw;
@ -108,7 +108,7 @@ class SymfonyProxy_46eafd3003c2798ed583593e686cb95e extends \Symfony\Component\D
}
}
class SymfonyProxy_78f39120a5353f811849a5b3f3e6d70c extends \Symfony\Component\DependencyInjection\Tests\Fixtures\Container29\Foo implements \Symfony\Component\DependencyInjection\LazyProxy\GetterProxyInterface
class SymfonyProxy_4a8df73e139322e3fa994cdec2f5b203 extends \Symfony\Component\DependencyInjection\Tests\Fixtures\Container29\Foo implements \Symfony\Component\DependencyInjection\LazyProxy\InheritanceProxyInterface
{
private $container6HqvH3fsTTC6dr66HyT2Jw;
private $getters6HqvH3fsTTC6dr66HyT2Jw;

View File

@ -67,7 +67,7 @@ class ProjectServiceContainer extends Container
return ${($_ = isset($this->services['foo']) ? $this->services['foo'] : $this->get('foo')) && false ?: '_'}->withVariadic($a, ...$c);
}, 1 => /** @closure-proxy Symfony\Component\DependencyInjection\Tests\Fixtures\Container32\Foo::withNullable */ function (?int $a) {
return ${($_ = isset($this->services['foo']) ? $this->services['foo'] : $this->get('foo')) && false ?: '_'}->withNullable($a);
}, 2 => /** @closure-proxy Symfony\Component\DependencyInjection\Tests\Fixtures\Container32\Foo::withReturnType */ function () {
}, 2 => /** @closure-proxy Symfony\Component\DependencyInjection\Tests\Fixtures\Container32\Foo::withReturnType */ function (): \Bar {
return ${($_ = isset($this->services['foo']) ? $this->services['foo'] : $this->get('foo')) && false ?: '_'}->withReturnType();
});

View File

@ -61,7 +61,7 @@ class Symfony_DI_PhpDumper_Test_Overriden_Getters_With_Constructor extends Conta
*/
protected function getBazService()
{
return $this->services['baz'] = $this->instantiateProxy(SymfonyProxy_a9f1de23b86d1fe2b860654ab2128883::class, array(), true);
return $this->services['baz'] = $this->instantiateProxy(SymfonyProxy_f0afdd0cd14cc92319c3f5d20cec315a::class, array(), true);
}
/**
@ -74,7 +74,7 @@ class Symfony_DI_PhpDumper_Test_Overriden_Getters_With_Constructor extends Conta
*/
protected function getFooService()
{
return $this->services['foo'] = new SymfonyProxy_cbcc1d1a7dc6a97b54a307ad6a012531($this);
return $this->services['foo'] = new SymfonyProxy_4fb8f9a44021ab78702917f65fade566($this);
}
private function instantiateProxy($class, $args, $useConstructor)
@ -97,7 +97,7 @@ class Symfony_DI_PhpDumper_Test_Overriden_Getters_With_Constructor extends Conta
}
}
class SymfonyProxy_a9f1de23b86d1fe2b860654ab2128883 extends \Symfony\Component\DependencyInjection\Tests\Fixtures\Container34\Baz implements \Symfony\Component\DependencyInjection\LazyProxy\GetterProxyInterface
class SymfonyProxy_f0afdd0cd14cc92319c3f5d20cec315a extends \Symfony\Component\DependencyInjection\Tests\Fixtures\Container34\Baz implements \Symfony\Component\DependencyInjection\LazyProxy\InheritanceProxyInterface
{
private $containerg3aCmsigw5jaB68sqMSEQQ;
private $gettersg3aCmsigw5jaB68sqMSEQQ;
@ -108,7 +108,7 @@ class SymfonyProxy_a9f1de23b86d1fe2b860654ab2128883 extends \Symfony\Component\D
}
}
class SymfonyProxy_cbcc1d1a7dc6a97b54a307ad6a012531 extends \Symfony\Component\DependencyInjection\Tests\Fixtures\Container34\Foo implements \Symfony\Component\DependencyInjection\LazyProxy\GetterProxyInterface
class SymfonyProxy_4fb8f9a44021ab78702917f65fade566 extends \Symfony\Component\DependencyInjection\Tests\Fixtures\Container34\Foo implements \Symfony\Component\DependencyInjection\LazyProxy\InheritanceProxyInterface
{
private $containerg3aCmsigw5jaB68sqMSEQQ;
private $gettersg3aCmsigw5jaB68sqMSEQQ;

View File

@ -573,10 +573,10 @@ class XmlFileLoaderTest extends \PHPUnit_Framework_TestCase
$loader->load('services23.xml');
$this->assertTrue($container->getDefinition('bar')->isAutowired());
$this->assertEquals(array('__construct'), $container->getDefinition('bar')->getAutowiredMethods());
$this->assertEquals(array('__construct'), $container->getDefinition('bar')->getAutowiredCalls());
$loader->load('services27.xml');
$this->assertEquals(array('set*', 'bar'), $container->getDefinition('autowire_array')->getAutowiredMethods());
$this->assertEquals(array('set*', 'bar'), $container->getDefinition('autowire_array')->getAutowiredCalls());
}
public function testGetter()
@ -659,15 +659,15 @@ class XmlFileLoaderTest extends \PHPUnit_Framework_TestCase
$this->assertFalse($container->getDefinition('no_defaults_child')->isAutowired());
}
public function testDefaultsWithAutowiredMethods()
public function testDefaultsWithAutowiredCalls()
{
$container = new ContainerBuilder();
$loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
$loader->load('services30.xml');
$this->assertSame(array('__construct'), $container->getDefinition('with_defaults')->getAutowiredMethods());
$this->assertSame(array('setFoo'), $container->getDefinition('no_defaults')->getAutowiredMethods());
$this->assertSame(array('setFoo'), $container->getDefinition('no_defaults_child')->getAutowiredMethods());
$this->assertSame(array(), $container->getDefinition('with_defaults_child')->getAutowiredMethods());
$this->assertSame(array('__construct'), $container->getDefinition('with_defaults')->getAutowiredCalls());
$this->assertSame(array('setFoo'), $container->getDefinition('no_defaults')->getAutowiredCalls());
$this->assertSame(array('setFoo'), $container->getDefinition('no_defaults_child')->getAutowiredCalls());
$this->assertSame(array(), $container->getDefinition('with_defaults_child')->getAutowiredCalls());
}
}

View File

@ -356,10 +356,10 @@ class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase
$loader->load('services23.yml');
$this->assertTrue($container->getDefinition('bar_service')->isAutowired());
$this->assertEquals(array('__construct'), $container->getDefinition('bar_service')->getAutowiredMethods());
$this->assertEquals(array('__construct'), $container->getDefinition('bar_service')->getAutowiredCalls());
$loader->load('services27.yml');
$this->assertEquals(array('set*', 'bar'), $container->getDefinition('autowire_array')->getAutowiredMethods());
$this->assertEquals(array('set*', 'bar'), $container->getDefinition('autowire_array')->getAutowiredCalls());
}
public function testClassFromId()

View File

@ -11,7 +11,7 @@
namespace Symfony\Component\VarDumper\Caster;
use Symfony\Component\DependencyInjection\LazyProxy\GetterProxyInterface;
use Symfony\Component\DependencyInjection\LazyProxy\InheritanceProxyInterface;
/**
* Represents a PHP class identifier.
@ -68,9 +68,9 @@ class ClassStub extends ConstStub
return;
}
if (interface_exists(GetterProxyInterface::class, false)) {
if (interface_exists(InheritanceProxyInterface::class, false)) {
$c = $r instanceof \ReflectionMethod ? $r->getDeclaringClass() : $r;
if ($c instanceof \ReflectionClass && $c->implementsInterface(GetterProxyInterface::class)) {
if ($c instanceof \ReflectionClass && $c->implementsInterface(InheritanceProxyInterface::class)) {
$p = $c->getParentClass();
$this->value = $identifier = str_replace($c->name, $p->name.'@proxy', $identifier);
if (0 < $i = strrpos($identifier, '\\')) {

View File

@ -11,7 +11,7 @@
namespace Symfony\Component\VarDumper\Caster;
use Symfony\Component\DependencyInjection\LazyProxy\GetterProxyInterface;
use Symfony\Component\DependencyInjection\LazyProxy\InheritanceProxyInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\VarDumper\Cloner\Stub;
@ -42,7 +42,7 @@ class SymfonyCaster
return $a;
}
public static function castGetterProxy(GetterProxyInterface $proxy, array $a, Stub $stub, $isNested)
public static function castInheritanceProxy(InheritanceProxyInterface $proxy, array $a, Stub $stub, $isNested)
{
$privatePrefix = sprintf("\0%s\0", $stub->class);
$stub->class = get_parent_class($proxy).'@proxy';

View File

@ -75,7 +75,7 @@ abstract class AbstractCloner implements ClonerInterface
'Exception' => 'Symfony\Component\VarDumper\Caster\ExceptionCaster::castException',
'Error' => 'Symfony\Component\VarDumper\Caster\ExceptionCaster::castError',
'Symfony\Component\DependencyInjection\ContainerInterface' => 'Symfony\Component\VarDumper\Caster\StubCaster::cutInternals',
'Symfony\Component\DependencyInjection\LazyProxy\GetterProxyInterface' => 'Symfony\Component\VarDumper\Caster\SymfonyCaster::castGetterProxy',
'Symfony\Component\DependencyInjection\LazyProxy\InheritanceProxyInterface' => 'Symfony\Component\VarDumper\Caster\SymfonyCaster::castInheritanceProxy',
'Symfony\Component\HttpFoundation\Request' => 'Symfony\Component\VarDumper\Caster\SymfonyCaster::castRequest',
'Symfony\Component\VarDumper\Exception\ThrowingCasterException' => 'Symfony\Component\VarDumper\Caster\ExceptionCaster::castThrowingCasterException',
'Symfony\Component\VarDumper\Caster\TraceStub' => 'Symfony\Component\VarDumper\Caster\ExceptionCaster::castTraceStub',