[DI] Refacto / cleanup / minor fixes
This commit is contained in:
parent
a736458fb5
commit
ad5b5b5d93
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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).')';
|
||||
}
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
@ -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
|
||||
{
|
||||
}
|
@ -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;
|
||||
|
@ -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'])) {
|
||||
|
@ -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()
|
||||
|
@ -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();
|
||||
|
@ -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()
|
||||
|
@ -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');
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -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');
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
});
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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, '\\')) {
|
||||
|
@ -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';
|
||||
|
@ -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',
|
||||
|
Reference in New Issue
Block a user