composer update

This commit is contained in:
Oliver Davies 2019-01-24 08:00:03 +00:00
parent f6abc3dce2
commit 71dfaca858
1753 changed files with 45274 additions and 14619 deletions

View file

@ -1,4 +1,4 @@
Copyright (c) 2004-2018 Fabien Potencier
Copyright (c) 2004-2019 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/5.2/phpunit.xsd"
backupGlobals="false"
colors="true"
bootstrap="vendor/autoload.php"

View file

@ -26,7 +26,7 @@ interface ConfigCacheFactoryInterface
* @param string $file The absolute cache file path
* @param callable $callable The callable to be executed when the cache needs to be filled (i. e. is not fresh). The cache will be passed as the only parameter to this callback
*
* @return ConfigCacheInterface $configCache The cache instance
* @return ConfigCacheInterface The cache instance
*/
public function cache($file, $callable);
}

View file

@ -92,7 +92,7 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface
/**
* Gets the xml remappings that should be performed.
*
* @return array $remappings an array of the form array(array(string, string))
* @return array an array of the form array(array(string, string))
*/
public function getXmlRemappings()
{
@ -292,7 +292,10 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface
$normalized = array();
foreach ($value as $name => $val) {
if (isset($this->children[$name])) {
$normalized[$name] = $this->children[$name]->normalize($val);
try {
$normalized[$name] = $this->children[$name]->normalize($val);
} catch (UnsetKeyException $e) {
}
unset($value[$name]);
} elseif (!$this->removeExtraKeys) {
$normalized[$name] = $val;

View file

@ -282,7 +282,7 @@ abstract class BaseNode implements NodeInterface
*
* @param $value
*
* @return $value The normalized array value
* @return The normalized array value
*/
protected function preNormalize($value)
{

View file

@ -174,7 +174,7 @@ class ExprBuilder
}
/**
* Sets a closure marking the value as invalid at validation time.
* Sets a closure marking the value as invalid at processing time.
*
* if you want to add the value of the node in your message just use a %s placeholder.
*
@ -192,7 +192,7 @@ class ExprBuilder
}
/**
* Sets a closure unsetting this key of the array at validation time.
* Sets a closure unsetting this key of the array at processing time.
*
* @return $this
*

View file

@ -133,7 +133,7 @@ class NodeBuilder implements NodeParentInterface
/**
* Returns the parent node.
*
* @return ParentNodeDefinitionInterface|NodeDefinition The parent node
* @return NodeDefinition&ParentNodeDefinitionInterface The parent node
*/
public function end()
{

View file

@ -345,7 +345,7 @@ abstract class NodeDefinition implements NodeParentInterface
/**
* Instantiate and configure the node according to this definition.
*
* @return NodeInterface $node The node instance
* @return NodeInterface The node instance
*
* @throws InvalidDefinitionException When the definition is invalid
*/

View file

@ -1,4 +1,4 @@
Copyright (c) 2004-2018 Fabien Potencier
Copyright (c) 2004-2019 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View file

@ -231,6 +231,25 @@ class ArrayNodeDefinitionTest extends TestCase
$this->assertFalse($this->getField($node, 'normalizeKeys'));
}
public function testUnsetChild()
{
$node = new ArrayNodeDefinition('root');
$node
->children()
->scalarNode('value')
->beforeNormalization()
->ifTrue(function ($value) {
return empty($value);
})
->thenUnset()
->end()
->end()
->end()
;
$this->assertSame(array(), $node->getNode()->normalize(array('value' => null)));
}
public function testPrototypeVariable()
{
$node = new ArrayNodeDefinition('root');

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/5.2/phpunit.xsd"
backupGlobals="false"
colors="true"
bootstrap="vendor/autoload.php"

View file

@ -74,7 +74,7 @@ class Application
private $dispatcher;
private $terminal;
private $defaultCommand;
private $singleCommand;
private $singleCommand = false;
private $initialized;
/**
@ -783,6 +783,13 @@ class Application
// exception related properties
$trace = $e->getTrace();
array_unshift($trace, array(
'function' => '',
'file' => $e->getFile() ?: 'n/a',
'line' => $e->getLine() ?: 'n/a',
'args' => array(),
));
for ($i = 0, $count = \count($trace); $i < $count; ++$i) {
$class = isset($trace[$i]['class']) ? $trace[$i]['class'] : '';
$type = isset($trace[$i]['type']) ? $trace[$i]['type'] : '';
@ -1155,6 +1162,14 @@ class Application
return $this;
}
/**
* @internal
*/
public function isSingleCommand()
{
return $this->singleCommand;
}
private function splitStringByWidth($string, $width)
{
// str_split is not suitable for multi-byte characters, we should use preg_split to get char array properly.

View file

@ -369,9 +369,9 @@ class Command
* Adds an argument.
*
* @param string $name The argument name
* @param int|null $mode The argument mode: self::REQUIRED or self::OPTIONAL
* @param int|null $mode The argument mode: InputArgument::REQUIRED or InputArgument::OPTIONAL
* @param string $description A description text
* @param string|string[]|null $default The default value (for self::OPTIONAL mode only)
* @param string|string[]|null $default The default value (for InputArgument::OPTIONAL mode only)
*
* @throws InvalidArgumentException When argument mode is not valid
*
@ -387,11 +387,11 @@ class Command
/**
* Adds an option.
*
* @param string $name The option name
* @param string|array $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts
* @param int|null $mode The option mode: One of the VALUE_* constants
* @param string $description A description text
* @param string|string[]|bool|null $default The default value (must be null for self::VALUE_NONE)
* @param string $name The option name
* @param string|array $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts
* @param int|null $mode The option mode: One of the InputOption::VALUE_* constants
* @param string $description A description text
* @param string|string[]|int|bool|null $default The default value (must be null for InputOption::VALUE_NONE)
*
* @throws InvalidArgumentException If option mode is invalid or incompatible
*
@ -533,6 +533,7 @@ class Command
public function getProcessedHelp()
{
$name = $this->name;
$isSingleCommand = $this->application && $this->application->isSingleCommand();
$placeholders = array(
'%command.name%',
@ -540,7 +541,7 @@ class Command
);
$replacements = array(
$name,
$_SERVER['PHP_SELF'].' '.$name,
$isSingleCommand ? $_SERVER['PHP_SELF'] : $_SERVER['PHP_SELF'].' '.$name,
);
return str_replace($placeholders, $replacements, $this->getHelp() ?: $this->getDescription());

View file

@ -157,7 +157,7 @@ class OutputFormatter implements OutputFormatterInterface
if (!$open && !$tag) {
// </>
$this->styleStack->pop();
} elseif (false === $style = $this->createStyleFromString(strtolower($tag))) {
} elseif (false === $style = $this->createStyleFromString($tag)) {
$output .= $this->applyCurrentStyle($text);
} elseif ($open) {
$this->styleStack->push($style);
@ -203,13 +203,14 @@ class OutputFormatter implements OutputFormatterInterface
$style = new OutputFormatterStyle();
foreach ($matches as $match) {
array_shift($match);
$match[0] = strtolower($match[0]);
if ('fg' == $match[0]) {
$style->setForeground($match[1]);
$style->setForeground(strtolower($match[1]));
} elseif ('bg' == $match[0]) {
$style->setBackground($match[1]);
$style->setBackground(strtolower($match[1]));
} elseif ('options' === $match[0]) {
preg_match_all('([^,;]+)', $match[1], $options);
preg_match_all('([^,;]+)', strtolower($match[1]), $options);
$options = array_shift($options);
foreach ($options as $option) {
try {

View file

@ -125,7 +125,7 @@ class TableStyle
/**
* Gets crossing character.
*
* @return string $crossingChar
* @return string
*/
public function getCrossingChar()
{

View file

@ -21,8 +21,6 @@ interface InputAwareInterface
{
/**
* Sets the Console Input.
*
* @param InputInterface
*/
public function setInput(InputInterface $input);
}

View file

@ -1,4 +1,4 @@
Copyright (c) 2004-2018 Fabien Potencier
Copyright (c) 2004-2019 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View file

@ -148,7 +148,10 @@ class CommandTester
{
$stream = fopen('php://memory', 'r+', false);
fwrite($stream, implode(PHP_EOL, $inputs));
foreach ($inputs as $input) {
fwrite($stream, $input.PHP_EOL);
}
rewind($stream);
return $stream;

View file

@ -776,6 +776,20 @@ class ApplicationTest extends TestCase
$this->assertStringMatchesFormatFile(self::$fixturesPath.'/application_renderexception_linebreaks.txt', $tester->getDisplay(true), '->renderException() keep multiple line breaks');
}
public function testRenderExceptionStackTraceContainsRootException()
{
$application = new Application();
$application->setAutoExit(false);
$application->register('foo')->setCode(function () {
throw new \Exception('Verbose exception');
});
$tester = new ApplicationTester($application);
$tester->run(array('command' => 'foo'), array('decorated' => false, 'verbosity' => Output::VERBOSITY_VERBOSE));
$this->assertContains(sprintf('() at %s:', __FILE__), $tester->getDisplay());
}
public function testRun()
{
$application = new Application();
@ -905,7 +919,7 @@ class ApplicationTest extends TestCase
$application->setAutoExit(false);
$application->expects($this->once())
->method('doRun')
->will($this->throwException($exception));
->willThrowException($exception);
$exitCode = $application->run(new ArrayInput(array()), new NullOutput());
@ -944,7 +958,7 @@ class ApplicationTest extends TestCase
$application->setAutoExit(false);
$application->expects($this->once())
->method('doRun')
->will($this->throwException($exception));
->willThrowException($exception);
$exitCode = $application->run(new ArrayInput(array()), new NullOutput());

View file

@ -166,6 +166,14 @@ class CommandTest extends TestCase
$command = new \TestCommand();
$command->setHelp('');
$this->assertContains('description', $command->getProcessedHelp(), '->getProcessedHelp() falls back to the description');
$command = new \TestCommand();
$command->setHelp('The %command.name% command does... Example: php %command.full_name%.');
$application = new Application();
$application->add($command);
$application->setDefaultCommand('namespace:name', true);
$this->assertContains('The namespace:name command does...', $command->getProcessedHelp(), '->getProcessedHelp() replaces %command.name% correctly in single command applications');
$this->assertNotContains('%command.full_name%', $command->getProcessedHelp(), '->getProcessedHelp() replaces %command.full_name% in single command applications');
}
public function testGetSetAliases()

View file

@ -112,6 +112,31 @@ class CommandTesterTest extends TestCase
$this->assertEquals(implode('', $questions), $tester->getDisplay(true));
}
public function testCommandWithDefaultInputs()
{
$questions = array(
'What\'s your name?',
'How are you?',
'Where do you come from?',
);
$command = new Command('foo');
$command->setHelperSet(new HelperSet(array(new QuestionHelper())));
$command->setCode(function ($input, $output) use ($questions, $command) {
$helper = $command->getHelper('question');
$helper->ask($input, $output, new Question($questions[0], 'Bobby'));
$helper->ask($input, $output, new Question($questions[1], 'Fine'));
$helper->ask($input, $output, new Question($questions[2], 'France'));
});
$tester = new CommandTester($command);
$tester->setInputs(array('', '', ''));
$tester->execute(array());
$this->assertEquals(0, $tester->getStatusCode());
$this->assertEquals(implode('', $questions), $tester->getDisplay(true));
}
/**
* @expectedException \RuntimeException
* @expectedMessage Aborted

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/5.2/phpunit.xsd"
backupGlobals="false"
colors="true"
bootstrap="vendor/autoload.php"

View file

@ -1,4 +1,4 @@
Copyright (c) 2004-2018 Fabien Potencier
Copyright (c) 2004-2019 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View file

@ -120,6 +120,9 @@ class ParserTest extends TestCase
array('a[name]', array('Attribute[Element[a][name]]')),
array("a[ name\t]", array('Attribute[Element[a][name]]')),
array('a [name]', array('CombinedSelector[Element[a] <followed> Attribute[Element[*][name]]]')),
array('[name="foo"]', array("Attribute[Element[*][name = 'foo']]")),
array("[name='foo[1]']", array("Attribute[Element[*][name = 'foo[1]']]")),
array("[name='foo[0][bar]']", array("Attribute[Element[*][name = 'foo[0][bar]']]")),
array('a[rel="include"]', array("Attribute[Element[a][rel = 'include']]")),
array('a[rel = include]', array("Attribute[Element[a][rel = 'include']]")),
array("a[hreflang |= 'en']", array("Attribute[Element[a][hreflang |= 'en']]")),

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/5.2/phpunit.xsd"
backupGlobals="false"
colors="true"
bootstrap="vendor/autoload.php"

View file

@ -138,14 +138,14 @@ class DebugClassLoader
try {
if ($this->isFinder && !isset($this->loaded[$class])) {
$this->loaded[$class] = true;
if ($file = $this->classLoader[0]->findFile($class) ?: false) {
$wasCached = \function_exists('opcache_is_script_cached') && @opcache_is_script_cached($file);
if (!$file = $this->classLoader[0]->findFile($class) ?: false) {
// no-op
} elseif (\function_exists('opcache_is_script_cached') && @opcache_is_script_cached($file)) {
require $file;
if ($wasCached) {
return;
}
return;
} else {
require $file;
}
} else {
\call_user_func($this->classLoader, $class);
@ -219,7 +219,7 @@ class DebugClassLoader
$len = 0;
$ns = '';
} else {
$ns = \substr($class, 0, $len);
$ns = \str_replace('_', '\\', \substr($class, 0, $len));
}
// Detect annotations on the class
@ -250,13 +250,13 @@ class DebugClassLoader
if (!isset(self::$checkedClasses[$use])) {
$this->checkClass($use);
}
if (isset(self::$deprecated[$use]) && \strncmp($ns, $use, $len)) {
if (isset(self::$deprecated[$use]) && \strncmp($ns, \str_replace('_', '\\', $use), $len)) {
$type = class_exists($class, false) ? 'class' : (interface_exists($class, false) ? 'interface' : 'trait');
$verb = class_exists($use, false) || interface_exists($class, false) ? 'extends' : (interface_exists($use, false) ? 'implements' : 'uses');
$deprecations[] = sprintf('The "%s" %s %s "%s" that is deprecated%s.', $class, $type, $verb, $use, self::$deprecated[$use]);
}
if (isset(self::$internal[$use]) && \strncmp($ns, $use, $len)) {
if (isset(self::$internal[$use]) && \strncmp($ns, \str_replace('_', '\\', $use), $len)) {
$deprecations[] = sprintf('The "%s" %s is considered internal%s. It may change without further notice. You should not use it from "%s".', $use, class_exists($use, false) ? 'class' : (interface_exists($use, false) ? 'interface' : 'trait'), self::$internal[$use], $class);
}
}

View file

@ -1,4 +1,4 @@
Copyright (c) 2004-2018 Fabien Potencier
Copyright (c) 2004-2019 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/5.2/phpunit.xsd"
backupGlobals="false"
colors="true"
bootstrap="vendor/autoload.php"

View file

@ -37,6 +37,7 @@ class AnalyzeServiceReferencesPass extends AbstractRecursivePass implements Repe
private $hasProxyDumper;
private $lazy;
private $expressionLanguage;
private $byConstructor;
/**
* @param bool $onlyConstructorArguments Sets this Service Reference pass to ignore method calls
@ -64,6 +65,7 @@ class AnalyzeServiceReferencesPass extends AbstractRecursivePass implements Repe
$this->graph = $container->getCompiler()->getServiceReferenceGraph();
$this->graph->clear();
$this->lazy = false;
$this->byConstructor = false;
foreach ($container->getAliases() as $id => $alias) {
$targetId = $this->getDefinitionId((string) $alias);
@ -100,7 +102,8 @@ class AnalyzeServiceReferencesPass extends AbstractRecursivePass implements Repe
$targetDefinition,
$value,
$this->lazy || ($this->hasProxyDumper && $targetDefinition && $targetDefinition->isLazy()),
ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $value->getInvalidBehavior()
ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $value->getInvalidBehavior(),
$this->byConstructor
);
return $value;
@ -118,8 +121,11 @@ class AnalyzeServiceReferencesPass extends AbstractRecursivePass implements Repe
}
$this->lazy = false;
$byConstructor = $this->byConstructor;
$this->byConstructor = true;
$this->processValue($value->getFactory());
$this->processValue($value->getArguments());
$this->byConstructor = $byConstructor;
if (!$this->onlyConstructorArguments) {
$this->processValue($value->getProperties());

View file

@ -452,7 +452,17 @@ class AutowirePass extends AbstractRecursivePass
private function createTypeNotFoundMessage(TypedReference $reference, $label)
{
if (!$r = $this->container->getReflectionClass($type = $reference->getType(), false)) {
$trackResources = $this->container->isTrackingResources();
$this->container->setResourceTracking(false);
try {
if ($r = $this->container->getReflectionClass($type = $reference->getType(), false)) {
$alternatives = $this->createTypeAlternatives($reference);
}
} finally {
$this->container->setResourceTracking($trackResources);
}
if (!$r) {
// either $type does not exist or a parent class does not exist
try {
$resource = new ClassExistenceResource($type, false);
@ -465,7 +475,6 @@ class AutowirePass extends AbstractRecursivePass
$message = sprintf('has type "%s" but this class %s.', $type, $parentMsg ? sprintf('is missing a parent class (%s)', $parentMsg) : 'was not found');
} else {
$alternatives = $this->createTypeAlternatives($reference);
$message = $this->container->has($type) ? 'this service is abstract' : 'no such service exists';
$message = sprintf('references %s "%s" but %s.%s', $r->isInterface() ? 'interface' : 'class', $type, $message, $alternatives);

View file

@ -127,13 +127,19 @@ class InlineServiceDefinitionsPass extends AbstractRecursivePass implements Repe
}
$ids = array();
$isReferencedByConstructor = false;
foreach ($graph->getNode($id)->getInEdges() as $edge) {
if ($edge->isWeak()) {
$isReferencedByConstructor = $isReferencedByConstructor || $edge->isReferencedByConstructor();
if ($edge->isWeak() || $edge->isLazy()) {
return false;
}
$ids[] = $edge->getSourceNode()->getId();
}
if (!$ids) {
return true;
}
if (\count(array_unique($ids)) > 1) {
return false;
}
@ -142,6 +148,10 @@ class InlineServiceDefinitionsPass extends AbstractRecursivePass implements Repe
return false;
}
return !$ids || $this->container->getDefinition($ids[0])->isShared();
if ($isReferencedByConstructor && $this->container->getDefinition($ids[0])->isLazy() && ($definition->getProperties() || $definition->getMethodCalls() || $definition->getConfigurator())) {
return false;
}
return $this->container->getDefinition($ids[0])->isShared();
}
}

View file

@ -51,12 +51,12 @@ class PassConfig
$this->optimizationPasses = array(array(
new ResolveChildDefinitionsPass(),
new ServiceLocatorTagPass(),
new RegisterServiceSubscribersPass(),
new DecoratorServicePass(),
new ResolveParameterPlaceHoldersPass(false),
new ResolveFactoryClassPass(),
new FactoryReturnTypePass($resolveClassPass),
new CheckDefinitionValidityPass(),
new RegisterServiceSubscribersPass(),
new ResolveNamedArgumentsPass(),
new AutowireRequiredMethodsPass(),
new ResolveBindingsPass(),

View file

@ -34,6 +34,8 @@ class ResolveBindingsPass extends AbstractRecursivePass
*/
public function process(ContainerBuilder $container)
{
$this->usedBindings = $container->getRemovedBindingIds();
try {
parent::process($container);

View file

@ -49,6 +49,7 @@ class ResolveNamedArgumentsPass extends AbstractRecursivePass
if (null === $parameters) {
$r = $this->getReflectionMethod($value, $method);
$class = $r instanceof \ReflectionMethod ? $r->class : $this->currentId;
$method = $r->getName();
$parameters = $r->getParameters();
}

View file

@ -91,11 +91,13 @@ class ServiceReferenceGraph
* @param string $reference
* @param bool $lazy
* @param bool $weak
* @param bool $byConstructor
*/
public function connect($sourceId, $sourceValue, $destId, $destValue = null, $reference = null/*, bool $lazy = false, bool $weak = false*/)
public function connect($sourceId, $sourceValue, $destId, $destValue = null, $reference = null/*, bool $lazy = false, bool $weak = false, bool $byConstructor = false*/)
{
$lazy = \func_num_args() >= 6 ? func_get_arg(5) : false;
$weak = \func_num_args() >= 7 ? func_get_arg(6) : false;
$byConstructor = \func_num_args() >= 8 ? func_get_arg(7) : false;
if (null === $sourceId || null === $destId) {
return;
@ -103,7 +105,7 @@ class ServiceReferenceGraph
$sourceNode = $this->createNode($sourceId, $sourceValue);
$destNode = $this->createNode($destId, $destValue);
$edge = new ServiceReferenceGraphEdge($sourceNode, $destNode, $reference, $lazy, $weak);
$edge = new ServiceReferenceGraphEdge($sourceNode, $destNode, $reference, $lazy, $weak, $byConstructor);
$sourceNode->addOutEdge($edge);
$destNode->addInEdge($edge);

View file

@ -25,6 +25,7 @@ class ServiceReferenceGraphEdge
private $value;
private $lazy;
private $weak;
private $byConstructor;
/**
* @param ServiceReferenceGraphNode $sourceNode
@ -32,14 +33,16 @@ class ServiceReferenceGraphEdge
* @param mixed $value
* @param bool $lazy
* @param bool $weak
* @param bool $byConstructor
*/
public function __construct(ServiceReferenceGraphNode $sourceNode, ServiceReferenceGraphNode $destNode, $value = null, $lazy = false, $weak = false)
public function __construct(ServiceReferenceGraphNode $sourceNode, ServiceReferenceGraphNode $destNode, $value = null, $lazy = false, $weak = false, $byConstructor = false)
{
$this->sourceNode = $sourceNode;
$this->destNode = $destNode;
$this->value = $value;
$this->lazy = $lazy;
$this->weak = $weak;
$this->byConstructor = $byConstructor;
}
/**
@ -91,4 +94,14 @@ class ServiceReferenceGraphEdge
{
return $this->weak;
}
/**
* Returns true if the edge links with a constructor argument.
*
* @return bool
*/
public function isReferencedByConstructor()
{
return $this->byConstructor;
}
}

View file

@ -123,6 +123,8 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
private $removedIds = array();
private $removedBindingIds = array();
private static $internalTypes = array(
'int' => true,
'float' => true,
@ -364,11 +366,11 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
try {
if (isset($this->classReflectors[$class])) {
$classReflector = $this->classReflectors[$class];
} elseif ($this->trackResources) {
} elseif (class_exists(ClassExistenceResource::class)) {
$resource = new ClassExistenceResource($class, false);
$classReflector = $resource->isFresh(0) ? false : new \ReflectionClass($class);
} else {
$classReflector = new \ReflectionClass($class);
$classReflector = class_exists($class) ? new \ReflectionClass($class) : false;
}
} catch (\ReflectionException $e) {
if ($throw) {
@ -531,7 +533,8 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
throw new BadMethodCallException(sprintf('Setting service "%s" for an unknown or non-synthetic service definition on a compiled container is not allowed.', $id));
}
unset($this->definitions[$id], $this->aliasDefinitions[$id], $this->removedIds[$id]);
$this->removeId($id);
unset($this->removedIds[$id]);
parent::set($id, $service);
}
@ -544,8 +547,7 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
public function removeDefinition($id)
{
if (isset($this->definitions[$id = $this->normalizeId($id)])) {
unset($this->definitions[$id]);
$this->removedIds[$id] = true;
$this->removeId($id);
}
}
@ -876,7 +878,8 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
throw new InvalidArgumentException(sprintf('An alias can not reference itself, got a circular reference on "%s".', $alias));
}
unset($this->definitions[$alias], $this->removedIds[$alias]);
$this->removeId($alias);
unset($this->removedIds[$alias]);
return $this->aliasDefinitions[$alias] = $id;
}
@ -889,8 +892,7 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
public function removeAlias($alias)
{
if (isset($this->aliasDefinitions[$alias = $this->normalizeId($alias)])) {
unset($this->aliasDefinitions[$alias]);
$this->removedIds[$alias] = true;
$this->removeId($alias);
}
}
@ -1019,7 +1021,8 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
$id = $this->normalizeId($id);
unset($this->aliasDefinitions[$id], $this->removedIds[$id]);
$this->removeId($id);
unset($this->removedIds[$id]);
return $this->definitions[$id] = $definition;
}
@ -1552,6 +1555,18 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
return $services;
}
/**
* Gets removed binding ids.
*
* @return array
*
* @internal
*/
public function getRemovedBindingIds()
{
return $this->removedBindingIds;
}
/**
* Computes a reasonably unique hash of a value.
*
@ -1656,4 +1671,21 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
return false;
}
private function removeId($id)
{
$this->removedIds[$id] = true;
unset($this->aliasDefinitions[$id]);
if (!isset($this->definitions[$id])) {
return;
}
foreach ($this->definitions[$id]->getBindings() as $binding) {
list(, $identifier) = $binding->getValues();
$this->removedBindingIds[$identifier] = true;
}
unset($this->definitions[$id]);
}
}

View file

@ -400,7 +400,7 @@ class Definition
/**
* Sets the definition templates to conditionally apply on the current definition, keyed by parent interface/class.
*
* @param $instanceof ChildDefinition[]
* @param ChildDefinition[] $instanceof
*
* @return $this
*/

View file

@ -149,6 +149,14 @@ class GraphvizDumper extends Dumper
$edges[] = array('name' => $name, 'required' => $required, 'to' => $argument, 'lazy' => $lazyEdge);
} elseif ($argument instanceof ArgumentInterface) {
$edges = array_merge($edges, $this->findEdges($id, $argument->getValues(), $required, $name, true));
} elseif ($argument instanceof Definition) {
$edges = array_merge($edges,
$this->findEdges($id, $argument->getArguments(), $required, ''),
$this->findEdges($id, $argument->getProperties(), false, '')
);
foreach ($argument->getMethodCalls() as $call) {
$edges = array_merge($edges, $this->findEdges($id, $call[1], false, $call[0].'()'));
}
} elseif (\is_array($argument)) {
$edges = array_merge($edges, $this->findEdges($id, $argument, $required, $name, $lazy));
}

View file

@ -154,14 +154,19 @@ class PhpDumper extends Dumper
}
}
(new AnalyzeServiceReferencesPass(false))->process($this->container);
$this->circularReferences = array();
(new AnalyzeServiceReferencesPass(false, !$this->getProxyDumper() instanceof NullDumper))->process($this->container);
$checkedNodes = array();
$this->circularReferences = array();
foreach ($this->container->getCompiler()->getServiceReferenceGraph()->getNodes() as $id => $node) {
$currentPath = array($id => $id);
$this->analyzeCircularReferences($node->getOutEdges(), $checkedNodes, $currentPath);
if (!$node->getValue() instanceof Definition) {
continue;
}
if (!isset($checkedNodes[$id])) {
$this->analyzeCircularReferences($id, $node->getOutEdges(), $checkedNodes);
}
}
$this->container->getCompiler()->getServiceReferenceGraph()->clear();
$checkedNodes = array();
$this->docStar = $options['debug'] ? '*' : '';
@ -297,26 +302,56 @@ EOF;
return $this->proxyDumper;
}
private function analyzeCircularReferences(array $edges, &$checkedNodes, &$currentPath)
private function analyzeCircularReferences($sourceId, array $edges, &$checkedNodes, &$currentPath = array())
{
$checkedNodes[$sourceId] = true;
$currentPath[$sourceId] = $sourceId;
foreach ($edges as $edge) {
$node = $edge->getDestNode();
$id = $node->getId();
if ($node->getValue() && ($edge->isLazy() || $edge->isWeak())) {
if (!$node->getValue() instanceof Definition || $sourceId === $id || $edge->isLazy() || $edge->isWeak()) {
// no-op
} elseif (isset($currentPath[$id])) {
$currentId = $id;
foreach (array_reverse($currentPath) as $parentId) {
$this->circularReferences[$parentId][$id] = $id;
$id = $parentId;
$this->circularReferences[$parentId][$currentId] = $currentId;
if ($parentId === $id) {
break;
}
$currentId = $parentId;
}
} elseif (!isset($checkedNodes[$id])) {
$checkedNodes[$id] = true;
$currentPath[$id] = $id;
$this->analyzeCircularReferences($node->getOutEdges(), $checkedNodes, $currentPath);
unset($currentPath[$id]);
$this->analyzeCircularReferences($id, $node->getOutEdges(), $checkedNodes, $currentPath);
} elseif (isset($this->circularReferences[$id])) {
$this->connectCircularReferences($id, $currentPath);
}
}
unset($currentPath[$sourceId]);
}
private function connectCircularReferences($sourceId, &$currentPath, &$subPath = array())
{
$subPath[$sourceId] = $sourceId;
$currentPath[$sourceId] = $sourceId;
foreach ($this->circularReferences[$sourceId] as $id) {
if (isset($currentPath[$id])) {
$currentId = $id;
foreach (array_reverse($currentPath) as $parentId) {
$this->circularReferences[$parentId][$currentId] = $currentId;
if ($parentId === $id) {
break;
}
$currentId = $parentId;
}
} elseif (!isset($subPath[$id]) && isset($this->circularReferences[$id])) {
$this->connectCircularReferences($id, $currentPath, $subPath);
}
}
unset($currentPath[$sourceId]);
unset($subPath[$sourceId]);
}
private function collectLineage($class, array &$lineage)
@ -557,7 +592,8 @@ EOF;
if (\is_array($callable)) {
if ($callable[0] instanceof Reference
|| ($callable[0] instanceof Definition && $this->definitionVariables->contains($callable[0]))) {
|| ($callable[0] instanceof Definition && $this->definitionVariables->contains($callable[0]))
) {
return sprintf(" %s->%s(\$%s);\n", $this->dumpValue($callable[0]), $callable[1], $variableName);
}
@ -591,7 +627,7 @@ EOF;
$this->definitionVariables = new \SplObjectStorage();
$this->referenceVariables = array();
$this->variableCount = 0;
$this->definitionVariables[$definition] = $this->referenceVariables[$id] = new Variable('instance');
$this->referenceVariables[$id] = new Variable('instance');
$return = array();
@ -663,22 +699,7 @@ EOF;
$code .= sprintf(" @trigger_error(%s, E_USER_DEPRECATED);\n\n", $this->export($definition->getDeprecationMessage($id)));
}
$head = $tail = '';
$arguments = array($definition->getArguments(), $definition->getFactory());
$this->addInlineVariables($head, $tail, $id, $arguments, true);
$code .= '' !== $head ? $head."\n" : '';
if ($arguments = array_filter(array($definition->getProperties(), $definition->getMethodCalls(), $definition->getConfigurator()))) {
$this->addInlineVariables($tail, $tail, $id, $arguments, false);
$tail .= '' !== $tail ? "\n" : '';
$tail .= $this->addServiceProperties($definition);
$tail .= $this->addServiceMethodCalls($definition);
$tail .= $this->addServiceConfigurator($definition);
}
$code .= $this->addServiceInstance($id, $definition, '' === $tail)
.('' !== $tail ? "\n".$tail."\n return \$instance;\n" : '');
$code .= $this->addInlineService($id, $definition);
if ($asFile) {
$code = implode("\n", array_map(function ($line) { return $line ? substr($line, 8) : $line; }, explode("\n", $code)));
@ -692,35 +713,45 @@ EOF;
return $code;
}
private function addInlineVariables(&$head, &$tail, $id, array $arguments, $forConstructor)
private function addInlineVariables($id, Definition $definition, array $arguments, $forConstructor)
{
$hasSelfRef = false;
$code = '';
foreach ($arguments as $argument) {
if (\is_array($argument)) {
$hasSelfRef = $this->addInlineVariables($head, $tail, $id, $argument, $forConstructor) || $hasSelfRef;
$code .= $this->addInlineVariables($id, $definition, $argument, $forConstructor);
} elseif ($argument instanceof Reference) {
$hasSelfRef = $this->addInlineReference($head, $id, $this->container->normalizeId($argument), $forConstructor) || $hasSelfRef;
$code .= $this->addInlineReference($id, $definition, $this->container->normalizeId($argument), $forConstructor);
} elseif ($argument instanceof Definition) {
$hasSelfRef = $this->addInlineService($head, $tail, $id, $argument, $forConstructor) || $hasSelfRef;
$code .= $this->addInlineService($id, $definition, $argument, $forConstructor);
}
}
return $hasSelfRef;
return $code;
}
private function addInlineReference(&$code, $id, $targetId, $forConstructor)
private function addInlineReference($id, Definition $definition, $targetId, $forConstructor)
{
$hasSelfRef = isset($this->circularReferences[$id][$targetId]);
if ('service_container' === $targetId || isset($this->referenceVariables[$targetId])) {
return $hasSelfRef;
}
list($callCount, $behavior) = $this->serviceCalls[$targetId];
if (2 > $callCount && (!$hasSelfRef || !$forConstructor)) {
return $hasSelfRef;
while ($this->container->hasAlias($targetId)) {
$targetId = (string) $this->container->getAlias($targetId);
}
if ($id === $targetId) {
return $this->addInlineService($id, $definition, $definition);
}
if ('service_container' === $targetId || isset($this->referenceVariables[$targetId])) {
return '';
}
$hasSelfRef = isset($this->circularReferences[$id][$targetId]);
$forConstructor = $forConstructor && !isset($this->definitionVariables[$definition]);
$code = $hasSelfRef && !$forConstructor ? $this->addInlineService($id, $definition, $definition) : '';
if (isset($this->referenceVariables[$targetId]) || (2 > $callCount && (!$hasSelfRef || !$forConstructor))) {
return $code;
}
$name = $this->getNextVariableName();
@ -730,7 +761,7 @@ EOF;
$code .= sprintf(" \$%s = %s;\n", $name, $this->getServiceCall($targetId, $reference));
if (!$hasSelfRef || !$forConstructor) {
return $hasSelfRef;
return $code;
}
$code .= sprintf(<<<'EOTXT'
@ -745,46 +776,56 @@ EOTXT
$id
);
return false;
return $code;
}
private function addInlineService(&$head, &$tail, $id, Definition $definition, $forConstructor)
private function addInlineService($id, Definition $definition, Definition $inlineDef = null, $forConstructor = true)
{
if (isset($this->definitionVariables[$definition])) {
return false;
$isSimpleInstance = $isRootInstance = null === $inlineDef;
if (isset($this->definitionVariables[$inlineDef = $inlineDef ?: $definition])) {
return '';
}
$arguments = array($definition->getArguments(), $definition->getFactory());
$arguments = array($inlineDef->getArguments(), $inlineDef->getFactory());
if (2 > $this->inlinedDefinitions[$definition] && !$definition->getMethodCalls() && !$definition->getProperties() && !$definition->getConfigurator()) {
return $this->addInlineVariables($head, $tail, $id, $arguments, $forConstructor);
$code = $this->addInlineVariables($id, $definition, $arguments, $forConstructor);
if ($arguments = array_filter(array($inlineDef->getProperties(), $inlineDef->getMethodCalls(), $inlineDef->getConfigurator()))) {
$isSimpleInstance = false;
} elseif ($definition !== $inlineDef && 2 > $this->inlinedDefinitions[$inlineDef]) {
return $code;
}
$name = $this->getNextVariableName();
$this->definitionVariables[$definition] = new Variable($name);
$code = '';
if ($forConstructor) {
$hasSelfRef = $this->addInlineVariables($code, $tail, $id, $arguments, $forConstructor);
if (isset($this->definitionVariables[$inlineDef])) {
$isSimpleInstance = false;
} else {
$hasSelfRef = $this->addInlineVariables($code, $code, $id, $arguments, $forConstructor);
}
$code .= $this->addNewInstance($definition, '$'.$name, ' = ', $id);
$hasSelfRef && !$forConstructor ? $tail .= ('' !== $tail ? "\n" : '').$code : $head .= ('' !== $head ? "\n" : '').$code;
$name = $definition === $inlineDef ? 'instance' : $this->getNextVariableName();
$this->definitionVariables[$inlineDef] = new Variable($name);
$code .= '' !== $code ? "\n" : '';
$code = '';
$arguments = array($definition->getProperties(), $definition->getMethodCalls(), $definition->getConfigurator());
$hasSelfRef = $this->addInlineVariables($code, $code, $id, $arguments, false) || $hasSelfRef;
if ('instance' === $name) {
$code .= $this->addServiceInstance($id, $definition, $isSimpleInstance);
} else {
$code .= $this->addNewInstance($inlineDef, '$'.$name, ' = ', $id);
}
$code .= '' !== $code ? "\n" : '';
$code .= $this->addServiceProperties($definition, $name);
$code .= $this->addServiceMethodCalls($definition, $name);
$code .= $this->addServiceConfigurator($definition, $name);
if ('' !== $code) {
$hasSelfRef ? $tail .= ('' !== $tail ? "\n" : '').$code : $head .= $code;
if ('' !== $inline = $this->addInlineVariables($id, $definition, $arguments, false)) {
$code .= "\n".$inline."\n";
} elseif ($arguments && 'instance' === $name) {
$code .= "\n";
}
$code .= $this->addServiceProperties($inlineDef, $name);
$code .= $this->addServiceMethodCalls($inlineDef, $name);
$code .= $this->addServiceConfigurator($inlineDef, $name);
}
return $hasSelfRef;
if ($isRootInstance && !$isSimpleInstance) {
$code .= "\n return \$instance;\n";
}
return $code;
}
/**
@ -1350,7 +1391,7 @@ EOF;
/*{$this->docStar}
* Computes a dynamic parameter.
*
* @param string The name of the dynamic parameter to load
* @param string \$name The name of the dynamic parameter to load
*
* @return mixed The value of the dynamic parameter
*
@ -1781,6 +1822,7 @@ EOF;
if ($definition->isShared()) {
$code = sprintf('$this->services[\'%s\'] = %s', $id, $code);
}
$code = "($code)";
} elseif ($this->asFiles && $definition->isShared() && !$this->isHotPath($definition)) {
$code = sprintf("\$this->load('%s.php')", $this->generateMethodName($id));
} else {

View file

@ -1,4 +1,4 @@
Copyright (c) 2004-2018 Fabien Potencier
Copyright (c) 2004-2019 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View file

@ -70,7 +70,9 @@ class IniFileLoader extends FileLoader
private function phpize($value)
{
// trim on the right as comments removal keep whitespaces
$value = rtrim($value);
if ($value !== $v = rtrim($value)) {
$value = '""' === substr_replace($v, '', 1, -1) ? substr($v, 1, -1) : $v;
}
$lowercaseValue = strtolower($value);
switch (true) {

View file

@ -595,7 +595,7 @@ class YamlFileLoader extends FileLoader
* @param string $id A service identifier
* @param string $file A parsed file
*
* @throws InvalidArgumentException When errors are occuried
* @throws InvalidArgumentException When errors occur
*
* @return string|array A parsed callable
*/

View file

@ -94,39 +94,40 @@ class ServiceLocator implements PsrContainerInterface
$class = isset($class[2]['object']) ? \get_class($class[2]['object']) : null;
$externalId = $this->externalId ?: $class;
$msg = sprintf('Service "%s" not found: ', $id);
$msg = array();
$msg[] = sprintf('Service "%s" not found:', $id);
if (!$this->container) {
$class = null;
} elseif ($this->container->has($id) || isset($this->container->getRemovedIds()[$id])) {
$msg .= 'even though it exists in the app\'s container, ';
$msg[] = 'even though it exists in the app\'s container,';
} else {
try {
$this->container->get($id);
$class = null;
} catch (ServiceNotFoundException $e) {
if ($e->getAlternatives()) {
$msg .= sprintf(' did you mean %s? Anyway, ', $this->formatAlternatives($e->getAlternatives(), 'or'));
$msg[] = sprintf('did you mean %s? Anyway,', $this->formatAlternatives($e->getAlternatives(), 'or'));
} else {
$class = null;
}
}
}
if ($externalId) {
$msg .= sprintf('the container inside "%s" is a smaller service locator that %s', $externalId, $this->formatAlternatives());
$msg[] = sprintf('the container inside "%s" is a smaller service locator that %s', $externalId, $this->formatAlternatives());
} else {
$msg .= sprintf('the current service locator %s', $this->formatAlternatives());
$msg[] = sprintf('the current service locator %s', $this->formatAlternatives());
}
if (!$class) {
// no-op
} elseif (is_subclass_of($class, ServiceSubscriberInterface::class)) {
$msg .= sprintf(' Unless you need extra laziness, try using dependency injection instead. Otherwise, you need to declare it using "%s::getSubscribedServices()".', preg_replace('/([^\\\\]++\\\\)++/', '', $class));
$msg[] = sprintf('Unless you need extra laziness, try using dependency injection instead. Otherwise, you need to declare it using "%s::getSubscribedServices()".', preg_replace('/([^\\\\]++\\\\)++/', '', $class));
} else {
$msg .= 'Try using dependency injection instead.';
$msg[] = 'Try using dependency injection instead.';
}
return $msg;
return implode(' ', $msg);
}
private function formatAlternatives(array $alternatives = null, $separator = 'and')

View file

@ -17,6 +17,7 @@ use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ServiceSubscriberInterface;
/**
* This class tests the integration of the different compiler passes.
@ -117,6 +118,21 @@ class IntegrationTest extends TestCase
$this->assertFalse($container->hasDefinition('c'), 'Service C was not inlined.');
}
public function testCanDecorateServiceSubscriber()
{
$container = new ContainerBuilder();
$container->register(ServiceSubscriberStub::class)
->addTag('container.service_subscriber')
->setPublic(true);
$container->register(DecoratedServiceSubscriber::class)
->setDecoratedService(ServiceSubscriberStub::class);
$container->compile();
$this->assertInstanceOf(DecoratedServiceSubscriber::class, $container->get(ServiceSubscriberStub::class));
}
/**
* @dataProvider getYamlCompileTests
*/
@ -207,6 +223,18 @@ class IntegrationTest extends TestCase
}
}
class ServiceSubscriberStub implements ServiceSubscriberInterface
{
public static function getSubscribedServices()
{
return array();
}
}
class DecoratedServiceSubscriber
{
}
class IntegrationTestStub extends IntegrationTestStubParent
{
}

View file

@ -111,4 +111,22 @@ class ResolveBindingsPassTest extends TestCase
$this->assertEquals(array(array('setDefaultLocale', array('fr'))), $definition->getMethodCalls());
}
public function testOverriddenBindings()
{
$container = new ContainerBuilder();
$binding = new BoundArgument('bar');
$container->register('foo', 'stdClass')
->setBindings(array('$foo' => clone $binding));
$container->register('bar', 'stdClass')
->setBindings(array('$foo' => clone $binding));
$container->register('foo', 'stdClass');
(new ResolveBindingsPass())->process($container);
$this->assertInstanceOf('stdClass', $container->get('foo'));
}
}

View file

@ -434,7 +434,7 @@ class ResolveChildDefinitionsPassTest extends TestCase
/**
* @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException
* @expectedExceptionMessageRegExp /^Circular reference detected for service "c", path: "c -> b -> a -> c"./
* @expectedExceptionMessageRegExp /^Circular reference detected for service "a", path: "a -> c -> b -> a"./
*/
public function testProcessDetectsChildDefinitionIndirectCircularReference()
{

View file

@ -16,8 +16,10 @@ use Symfony\Component\DependencyInjection\Compiler\ResolveNamedArgumentsPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Tests\Fixtures\CaseSensitiveClass;
use Symfony\Component\DependencyInjection\Tests\Fixtures\FactoryDummyWithoutReturnTypes;
use Symfony\Component\DependencyInjection\Tests\Fixtures\NamedArgumentsDummy;
use Symfony\Component\DependencyInjection\Tests\Fixtures\SimilarArgumentsDummy;
use Symfony\Component\DependencyInjection\Tests\Fixtures\TestDefinition1;
/**
* @author Kévin Dunglas <dunglas@gmail.com>
@ -102,6 +104,7 @@ class ResolveNamedArgumentsPassTest extends TestCase
/**
* @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
* @expectedExceptionMessage Invalid service "Symfony\Component\DependencyInjection\Tests\Fixtures\NamedArgumentsDummy": method "__construct()" has no argument named "$notFound". Check your service definition.
*/
public function testArgumentNotFound()
{
@ -114,6 +117,24 @@ class ResolveNamedArgumentsPassTest extends TestCase
$pass->process($container);
}
/**
* @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
* @expectedExceptionMessage Invalid service "Symfony\Component\DependencyInjection\Tests\Fixtures\TestDefinition1": method "Symfony\Component\DependencyInjection\Tests\Fixtures\FactoryDummyWithoutReturnTypes::createTestDefinition1()" has no argument named "$notFound". Check your service definition.
*/
public function testCorrectMethodReportedInException()
{
$container = new ContainerBuilder();
$container->register(FactoryDummyWithoutReturnTypes::class, FactoryDummyWithoutReturnTypes::class);
$definition = $container->register(TestDefinition1::class, TestDefinition1::class);
$definition->setFactory(array(FactoryDummyWithoutReturnTypes::class, 'createTestDefinition1'));
$definition->setArguments(array('$notFound' => '123'));
$pass = new ResolveNamedArgumentsPass();
$pass->process($container);
}
public function testTypedArgument()
{
$container = new ContainerBuilder();

View file

@ -559,7 +559,7 @@ class ContainerBuilderTest extends TestCase
$config->setDefinition('baz', new Definition('BazClass'));
$config->setAlias('alias_for_foo', 'foo');
$container->merge($config);
$this->assertEquals(array('service_container', 'foo', 'bar', 'baz'), array_keys($container->getDefinitions()), '->merge() merges definitions already defined ones');
$this->assertEquals(array('foo', 'bar', 'service_container', 'baz'), array_keys($container->getDefinitions()), '->merge() merges definitions already defined ones');
$aliases = $container->getAliases();
$this->assertArrayHasKey('alias_for_foo', $aliases);
@ -1388,6 +1388,8 @@ class ContainerBuilderTest extends TestCase
$foo6 = $container->get('foo6');
$this->assertEquals((object) array('bar6' => (object) array()), $foo6);
$this->assertInstanceOf(\stdClass::class, $container->get('root'));
}
public function provideAlmostCircular()

View file

@ -13,7 +13,9 @@ namespace Symfony\Component\DependencyInjection\Tests\Dumper;
use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Dumper\GraphvizDumper;
use Symfony\Component\DependencyInjection\Reference;
class GraphvizDumperTest extends TestCase
{
@ -32,11 +34,11 @@ class GraphvizDumperTest extends TestCase
$container = include self::$fixturesPath.'/containers/container9.php';
$dumper = new GraphvizDumper($container);
$this->assertEquals(str_replace('%path%', __DIR__, file_get_contents(self::$fixturesPath.'/graphviz/services9.dot')), $dumper->dump(), '->dump() dumps services');
$this->assertStringEqualsFile(self::$fixturesPath.'/graphviz/services9.dot', $dumper->dump(), '->dump() dumps services');
$container = include self::$fixturesPath.'/containers/container10.php';
$dumper = new GraphvizDumper($container);
$this->assertEquals(str_replace('%path%', __DIR__, file_get_contents(self::$fixturesPath.'/graphviz/services10.dot')), $dumper->dump(), '->dump() dumps services');
$this->assertStringEqualsFile(self::$fixturesPath.'/graphviz/services10.dot', $dumper->dump(), '->dump() dumps services');
$container = include self::$fixturesPath.'/containers/container10.php';
$dumper = new GraphvizDumper($container);
@ -47,21 +49,21 @@ class GraphvizDumperTest extends TestCase
'node.instance' => array('fillcolor' => 'green', 'style' => 'empty'),
'node.definition' => array('fillcolor' => 'grey'),
'node.missing' => array('fillcolor' => 'red', 'style' => 'empty'),
)), str_replace('%path%', __DIR__, file_get_contents(self::$fixturesPath.'/graphviz/services10-1.dot')), '->dump() dumps services');
)), file_get_contents(self::$fixturesPath.'/graphviz/services10-1.dot'), '->dump() dumps services');
}
public function testDumpWithFrozenContainer()
{
$container = include self::$fixturesPath.'/containers/container13.php';
$dumper = new GraphvizDumper($container);
$this->assertEquals(str_replace('%path%', __DIR__, file_get_contents(self::$fixturesPath.'/graphviz/services13.dot')), $dumper->dump(), '->dump() dumps services');
$this->assertStringEqualsFile(self::$fixturesPath.'/graphviz/services13.dot', $dumper->dump(), '->dump() dumps services');
}
public function testDumpWithFrozenCustomClassContainer()
{
$container = include self::$fixturesPath.'/containers/container14.php';
$dumper = new GraphvizDumper($container);
$this->assertEquals(str_replace('%path%', __DIR__, file_get_contents(self::$fixturesPath.'/graphviz/services14.dot')), $dumper->dump(), '->dump() dumps services');
$this->assertStringEqualsFile(self::$fixturesPath.'/graphviz/services14.dot', $dumper->dump(), '->dump() dumps services');
}
public function testDumpWithUnresolvedParameter()
@ -69,6 +71,18 @@ class GraphvizDumperTest extends TestCase
$container = include self::$fixturesPath.'/containers/container17.php';
$dumper = new GraphvizDumper($container);
$this->assertEquals(str_replace('%path%', __DIR__, file_get_contents(self::$fixturesPath.'/graphviz/services17.dot')), $dumper->dump(), '->dump() dumps services');
$this->assertStringEqualsFile(self::$fixturesPath.'/graphviz/services17.dot', $dumper->dump(), '->dump() dumps services');
}
public function testDumpWithInlineDefinition()
{
$container = new ContainerBuilder();
$container->register('foo', 'stdClass')->addArgument(
(new Definition('stdClass'))->addArgument(new Reference('bar'))
);
$container->register('bar', 'stdClass');
$dumper = new GraphvizDumper($container);
$this->assertStringEqualsFile(self::$fixturesPath.'/graphviz/services_inline.dot', $dumper->dump(), '->dump() dumps nested references');
}
}

View file

@ -752,7 +752,7 @@ class PhpDumperTest extends TestCase
->setPublic(false);
$container->register('public_foo', 'stdClass')
->setPublic(true)
->addArgument(new Expression('service("private_foo")'));
->addArgument(new Expression('service("private_foo").bar'));
$container->compile();
$dumper = new PhpDumper($container);
@ -833,6 +833,8 @@ class PhpDumperTest extends TestCase
$foo6 = $container->get('foo6');
$this->assertEquals((object) array('bar6' => (object) array()), $foo6);
$this->assertInstanceOf(\stdClass::class, $container->get('root'));
}
public function provideAlmostCircular()

View file

@ -0,0 +1,19 @@
<?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\Tests\Fixtures;
class FactoryDummyWithoutReturnTypes
{
public function createTestDefinition1()
{
}
}

View file

@ -0,0 +1,19 @@
<?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\Tests\Fixtures;
class FooForCircularWithAddCalls
{
public function call(\stdClass $argument)
{
}
}

View file

@ -0,0 +1,18 @@
<?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\Tests\Fixtures;
use Symfony\Component\DependencyInjection\Definition;
class TestDefinition1 extends Definition
{
}

View file

@ -4,6 +4,9 @@ services:
class: Symfony\Component\DependencyInjection\ContainerInterface
public: true
synthetic: true
foo:
class: App\FooService
public: true
Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo:
class: Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo
public: true
@ -16,6 +19,3 @@ services:
shared: false
configurator: c
foo:
class: App\FooService
public: true

View file

@ -4,15 +4,6 @@ services:
class: Symfony\Component\DependencyInjection\ContainerInterface
public: true
synthetic: true
Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo:
class: Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo
public: true
tags:
- { name: foo }
- { name: baz }
deprecated: '%service_id%'
arguments: [1]
factory: f
Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Sub\Bar:
class: Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Sub\Bar
public: true
@ -23,3 +14,12 @@ services:
lazy: true
arguments: [1]
factory: f
Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo:
class: Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo
public: true
tags:
- { name: foo }
- { name: baz }
deprecated: '%service_id%'
arguments: [1]
factory: f

View file

@ -4,6 +4,7 @@ use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Tests\Fixtures\FooForCircularWithAddCalls;
$public = 'public' === $visibility;
$container = new ContainerBuilder();
@ -115,4 +116,33 @@ $container->register('baz6', 'stdClass')
->setPublic(true)
->setProperty('bar6', new Reference('bar6'));
// provided by Christian Schiffler
$container
->register('root', 'stdClass')
->setArguments([new Reference('level2'), new Reference('multiuse1')])
->setPublic(true);
$container
->register('level2', FooForCircularWithAddCalls::class)
->addMethodCall('call', [new Reference('level3')]);
$container->register('multiuse1', 'stdClass');
$container
->register('level3', 'stdClass')
->addArgument(new Reference('level4'));
$container
->register('level4', 'stdClass')
->setArguments([new Reference('multiuse1'), new Reference('level5')]);
$container
->register('level5', 'stdClass')
->addArgument(new Reference('level6'));
$container
->register('level6', FooForCircularWithAddCalls::class)
->addMethodCall('call', [new Reference('level5')]);
return $container;

View file

@ -0,0 +1,10 @@
digraph sc {
ratio="compress"
node [fontsize="11" fontname="Arial" shape="record"];
edge [fontsize="9" fontname="Arial" color="grey" arrowhead="open" arrowsize="0.5"];
node_service_container [label="service_container (Psr\Container\ContainerInterface, Symfony\Component\DependencyInjection\ContainerInterface)\nSymfony\\Component\\DependencyInjection\\ContainerInterface\n", shape=record, fillcolor="#eeeeee", style="filled"];
node_foo [label="foo\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
node_bar [label="bar\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
node_foo -> node_bar [label="" style="filled"];
}

View file

@ -11,9 +11,10 @@
constant = PHP_VERSION
12 = 12
12_string = '12'
12_quoted_number = "12"
12_comment = 12 ; comment
12_string_comment = '12' ; comment
12_string_comment_again = "12" ; comment
12_quoted_number_comment = "12" ; comment
-12 = -12
0 = 0
1 = 1

View file

@ -115,7 +115,7 @@ class ProjectServiceContainer extends Container
/**
* Computes a dynamic parameter.
*
* @param string The name of the dynamic parameter to load
* @param string $name The name of the dynamic parameter to load
*
* @return mixed The value of the dynamic parameter
*

View file

@ -122,7 +122,7 @@ class ProjectServiceContainer extends Container
/**
* Computes a dynamic parameter.
*
* @param string The name of the dynamic parameter to load
* @param string $name The name of the dynamic parameter to load
*
* @return mixed The value of the dynamic parameter
*

View file

@ -132,7 +132,7 @@ class ProjectServiceContainer extends Container
/**
* Computes a dynamic parameter.
*
* @param string The name of the dynamic parameter to load
* @param string $name The name of the dynamic parameter to load
*
* @return mixed The value of the dynamic parameter
*

View file

@ -138,7 +138,7 @@ class Symfony_DI_PhpDumper_Test_EnvParameters extends Container
/**
* Computes a dynamic parameter.
*
* @param string The name of the dynamic parameter to load
* @param string $name The name of the dynamic parameter to load
*
* @return mixed The value of the dynamic parameter
*

View file

@ -102,7 +102,7 @@ class ProjectServiceContainer extends Container
/**
* Computes a dynamic parameter.
*
* @param string The name of the dynamic parameter to load
* @param string $name The name of the dynamic parameter to load
*
* @return mixed The value of the dynamic parameter
*

View file

@ -126,7 +126,7 @@ class ProjectServiceContainer extends Container
{
$this->services['configured_service_simple'] = $instance = new \stdClass();
${($_ = isset($this->services['configurator_service_simple']) ? $this->services['configurator_service_simple'] : $this->services['configurator_service_simple'] = new \ConfClass('bar')) && false ?: '_'}->configureStdClass($instance);
${($_ = isset($this->services['configurator_service_simple']) ? $this->services['configurator_service_simple'] : ($this->services['configurator_service_simple'] = new \ConfClass('bar'))) && false ?: '_'}->configureStdClass($instance);
return $instance;
}

View file

@ -158,7 +158,6 @@ use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
$this->services['foo_with_inline'] = $instance = new \Foo();
$a = new \Bar();
$a->pub = 'pub';
$a->setBaz(${($_ = isset($this->services['baz']) ? $this->services['baz'] : $this->load('getBazService.php')) && false ?: '_'});
@ -244,7 +243,7 @@ use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
return $this->services['tagged_iterator'] = new \Bar(new RewindableGenerator(function () {
yield 0 => ${($_ = isset($this->services['foo']) ? $this->services['foo'] : $this->load('getFooService.php')) && false ?: '_'};
yield 1 => ${($_ = isset($this->services['tagged_iterator_foo']) ? $this->services['tagged_iterator_foo'] : $this->services['tagged_iterator_foo'] = new \Bar()) && false ?: '_'};
yield 1 => ${($_ = isset($this->services['tagged_iterator_foo']) ? $this->services['tagged_iterator_foo'] : ($this->services['tagged_iterator_foo'] = new \Bar())) && false ?: '_'};
}, 2));
[Container%s/getTaggedIteratorFooService.php] => <?php
@ -442,7 +441,7 @@ class ProjectServiceContainer extends Container
/**
* Computes a dynamic parameter.
*
* @param string The name of the dynamic parameter to load
* @param string $name The name of the dynamic parameter to load
*
* @return mixed The value of the dynamic parameter
*

View file

@ -264,7 +264,6 @@ class ProjectServiceContainer extends Container
$this->services['foo_with_inline'] = $instance = new \Foo();
$a = new \Bar();
$a->pub = 'pub';
$a->setBaz(${($_ = isset($this->services['baz']) ? $this->services['baz'] : $this->getBazService()) && false ?: '_'});
@ -356,7 +355,7 @@ class ProjectServiceContainer extends Container
{
return $this->services['tagged_iterator'] = new \Bar(new RewindableGenerator(function () {
yield 0 => ${($_ = isset($this->services['foo']) ? $this->services['foo'] : $this->getFooService()) && false ?: '_'};
yield 1 => ${($_ = isset($this->services['tagged_iterator_foo']) ? $this->services['tagged_iterator_foo'] : $this->services['tagged_iterator_foo'] = new \Bar()) && false ?: '_'};
yield 1 => ${($_ = isset($this->services['tagged_iterator_foo']) ? $this->services['tagged_iterator_foo'] : ($this->services['tagged_iterator_foo'] = new \Bar())) && false ?: '_'};
}, 2));
}
@ -433,7 +432,7 @@ class ProjectServiceContainer extends Container
/**
* Computes a dynamic parameter.
*
* @param string The name of the dynamic parameter to load
* @param string $name The name of the dynamic parameter to load
*
* @return mixed The value of the dynamic parameter
*

View file

@ -133,7 +133,13 @@ class ProjectServiceContainer extends Container
*/
protected function getHandler2Service()
{
return $this->services['App\Handler2'] = new \App\Handler2(${($_ = isset($this->services['App\Db']) ? $this->services['App\Db'] : $this->getDbService()) && false ?: '_'}, ${($_ = isset($this->services['App\Schema']) ? $this->services['App\Schema'] : $this->getSchemaService()) && false ?: '_'}, ${($_ = isset($this->services['App\Processor']) ? $this->services['App\Processor'] : $this->getProcessorService()) && false ?: '_'});
$a = ${($_ = isset($this->services['App\Processor']) ? $this->services['App\Processor'] : $this->getProcessorService()) && false ?: '_'};
if (isset($this->services['App\Handler2'])) {
return $this->services['App\Handler2'];
}
return $this->services['App\Handler2'] = new \App\Handler2(${($_ = isset($this->services['App\Db']) ? $this->services['App\Db'] : $this->getDbService()) && false ?: '_'}, ${($_ = isset($this->services['App\Schema']) ? $this->services['App\Schema'] : $this->getSchemaService()) && false ?: '_'}, $a);
}
/**

View file

@ -34,13 +34,26 @@ class Symfony_DI_PhpDumper_Test_Almost_Circular_Private extends Container
'foo5' => 'getFoo5Service',
'foo6' => 'getFoo6Service',
'foobar4' => 'getFoobar4Service',
'level2' => 'getLevel2Service',
'level3' => 'getLevel3Service',
'level4' => 'getLevel4Service',
'level5' => 'getLevel5Service',
'level6' => 'getLevel6Service',
'logger' => 'getLoggerService',
'manager' => 'getManagerService',
'manager2' => 'getManager2Service',
'multiuse1' => 'getMultiuse1Service',
'root' => 'getRootService',
'subscriber' => 'getSubscriberService',
);
$this->privates = array(
'bar6' => true,
'level2' => true,
'level3' => true,
'level4' => true,
'level5' => true,
'level6' => true,
'multiuse1' => true,
);
$this->aliases = array();
@ -62,7 +75,13 @@ class Symfony_DI_PhpDumper_Test_Almost_Circular_Private extends Container
'foobar' => true,
'foobar2' => true,
'foobar3' => true,
'level2' => true,
'level3' => true,
'level4' => true,
'level5' => true,
'level6' => true,
'logger2' => true,
'multiuse1' => true,
'subscriber2' => true,
);
}
@ -141,10 +160,10 @@ class Symfony_DI_PhpDumper_Test_Almost_Circular_Private extends Container
$this->services['connection'] = $instance = new \stdClass($a, $b);
$a->subscriber = ${($_ = isset($this->services['subscriber']) ? $this->services['subscriber'] : $this->getSubscriberService()) && false ?: '_'};
$b->logger = ${($_ = isset($this->services['logger']) ? $this->services['logger'] : $this->getLoggerService()) && false ?: '_'};
$a->subscriber = ${($_ = isset($this->services['subscriber']) ? $this->services['subscriber'] : $this->getSubscriberService()) && false ?: '_'};
return $instance;
}
@ -157,19 +176,19 @@ class Symfony_DI_PhpDumper_Test_Almost_Circular_Private extends Container
{
$a = new \stdClass();
$c = new \stdClass();
$b = new \stdClass();
$this->services['connection2'] = $instance = new \stdClass($a, $c);
$this->services['connection2'] = $instance = new \stdClass($a, $b);
$b = ${($_ = isset($this->services['manager2']) ? $this->services['manager2'] : $this->getManager2Service()) && false ?: '_'};
$c = new \stdClass($instance);
$a->subscriber2 = new \stdClass($b);
$d = ${($_ = isset($this->services['manager2']) ? $this->services['manager2'] : $this->getManager2Service()) && false ?: '_'};
$d = new \stdClass($instance);
$c->handler2 = new \stdClass($d);
$d->handler2 = new \stdClass($b);
$b->logger2 = $c;
$c->logger2 = $d;
$a->subscriber2 = new \stdClass($d);
return $instance;
}
@ -216,7 +235,6 @@ class Symfony_DI_PhpDumper_Test_Almost_Circular_Private extends Container
$this->services['foo5'] = $instance = new \stdClass();
$a = new \stdClass($instance);
$a->foo = $instance;
$instance->bar = $a;
@ -306,6 +324,16 @@ class Symfony_DI_PhpDumper_Test_Almost_Circular_Private extends Container
return $this->services['manager2'] = new \stdClass($a);
}
/**
* Gets the public 'root' shared service.
*
* @return \stdClass
*/
protected function getRootService()
{
return $this->services['root'] = new \stdClass(${($_ = isset($this->services['level2']) ? $this->services['level2'] : $this->getLevel2Service()) && false ?: '_'}, ${($_ = isset($this->services['multiuse1']) ? $this->services['multiuse1'] : ($this->services['multiuse1'] = new \stdClass())) && false ?: '_'});
}
/**
* Gets the public 'subscriber' shared service.
*
@ -337,4 +365,78 @@ class Symfony_DI_PhpDumper_Test_Almost_Circular_Private extends Container
return $this->services['bar6'] = new \stdClass($a);
}
/**
* Gets the private 'level2' shared service.
*
* @return \Symfony\Component\DependencyInjection\Tests\Fixtures\FooForCircularWithAddCalls
*/
protected function getLevel2Service()
{
$this->services['level2'] = $instance = new \Symfony\Component\DependencyInjection\Tests\Fixtures\FooForCircularWithAddCalls();
$instance->call(${($_ = isset($this->services['level3']) ? $this->services['level3'] : $this->getLevel3Service()) && false ?: '_'});
return $instance;
}
/**
* Gets the private 'level3' shared service.
*
* @return \stdClass
*/
protected function getLevel3Service()
{
return $this->services['level3'] = new \stdClass(${($_ = isset($this->services['level4']) ? $this->services['level4'] : $this->getLevel4Service()) && false ?: '_'});
}
/**
* Gets the private 'level4' shared service.
*
* @return \stdClass
*/
protected function getLevel4Service()
{
return $this->services['level4'] = new \stdClass(${($_ = isset($this->services['multiuse1']) ? $this->services['multiuse1'] : ($this->services['multiuse1'] = new \stdClass())) && false ?: '_'}, ${($_ = isset($this->services['level5']) ? $this->services['level5'] : $this->getLevel5Service()) && false ?: '_'});
}
/**
* Gets the private 'level5' shared service.
*
* @return \stdClass
*/
protected function getLevel5Service()
{
$a = ${($_ = isset($this->services['level6']) ? $this->services['level6'] : $this->getLevel6Service()) && false ?: '_'};
if (isset($this->services['level5'])) {
return $this->services['level5'];
}
return $this->services['level5'] = new \stdClass($a);
}
/**
* Gets the private 'level6' shared service.
*
* @return \Symfony\Component\DependencyInjection\Tests\Fixtures\FooForCircularWithAddCalls
*/
protected function getLevel6Service()
{
$this->services['level6'] = $instance = new \Symfony\Component\DependencyInjection\Tests\Fixtures\FooForCircularWithAddCalls();
$instance->call(${($_ = isset($this->services['level5']) ? $this->services['level5'] : $this->getLevel5Service()) && false ?: '_'});
return $instance;
}
/**
* Gets the private 'multiuse1' shared service.
*
* @return \stdClass
*/
protected function getMultiuse1Service()
{
return $this->services['multiuse1'] = new \stdClass();
}
}

View file

@ -41,13 +41,26 @@ class Symfony_DI_PhpDumper_Test_Almost_Circular_Public extends Container
'foobar2' => 'getFoobar2Service',
'foobar3' => 'getFoobar3Service',
'foobar4' => 'getFoobar4Service',
'level2' => 'getLevel2Service',
'level3' => 'getLevel3Service',
'level4' => 'getLevel4Service',
'level5' => 'getLevel5Service',
'level6' => 'getLevel6Service',
'logger' => 'getLoggerService',
'manager' => 'getManagerService',
'manager2' => 'getManager2Service',
'multiuse1' => 'getMultiuse1Service',
'root' => 'getRootService',
'subscriber' => 'getSubscriberService',
);
$this->privates = array(
'bar6' => true,
'level2' => true,
'level3' => true,
'level4' => true,
'level5' => true,
'level6' => true,
'multiuse1' => true,
);
$this->aliases = array();
@ -62,7 +75,13 @@ class Symfony_DI_PhpDumper_Test_Almost_Circular_Public extends Container
'bar6' => true,
'config' => true,
'config2' => true,
'level2' => true,
'level3' => true,
'level4' => true,
'level5' => true,
'level6' => true,
'logger2' => true,
'multiuse1' => true,
'subscriber2' => true,
);
}
@ -107,7 +126,7 @@ class Symfony_DI_PhpDumper_Test_Almost_Circular_Public extends Container
{
$this->services['bar3'] = $instance = new \BarCircular();
$a = ${($_ = isset($this->services['foobar3']) ? $this->services['foobar3'] : $this->services['foobar3'] = new \FoobarCircular()) && false ?: '_'};
$a = ${($_ = isset($this->services['foobar3']) ? $this->services['foobar3'] : ($this->services['foobar3'] = new \FoobarCircular())) && false ?: '_'};
$instance->addFoobar($a, $a);
@ -155,11 +174,16 @@ class Symfony_DI_PhpDumper_Test_Almost_Circular_Public extends Container
*/
protected function getConnectionService()
{
$a = new \stdClass();
$a = ${($_ = isset($this->services['dispatcher']) ? $this->services['dispatcher'] : $this->getDispatcherService()) && false ?: '_'};
$this->services['connection'] = $instance = new \stdClass(${($_ = isset($this->services['dispatcher']) ? $this->services['dispatcher'] : $this->getDispatcherService()) && false ?: '_'}, $a);
if (isset($this->services['connection'])) {
return $this->services['connection'];
}
$b = new \stdClass();
$a->logger = ${($_ = isset($this->services['logger']) ? $this->services['logger'] : $this->getLoggerService()) && false ?: '_'};
$this->services['connection'] = $instance = new \stdClass($a, $b);
$b->logger = ${($_ = isset($this->services['logger']) ? $this->services['logger'] : $this->getLoggerService()) && false ?: '_'};
return $instance;
}
@ -171,15 +195,19 @@ class Symfony_DI_PhpDumper_Test_Almost_Circular_Public extends Container
*/
protected function getConnection2Service()
{
$a = new \stdClass();
$a = ${($_ = isset($this->services['dispatcher2']) ? $this->services['dispatcher2'] : $this->getDispatcher2Service()) && false ?: '_'};
$this->services['connection2'] = $instance = new \stdClass(${($_ = isset($this->services['dispatcher2']) ? $this->services['dispatcher2'] : $this->getDispatcher2Service()) && false ?: '_'}, $a);
if (isset($this->services['connection2'])) {
return $this->services['connection2'];
}
$b = new \stdClass();
$b = new \stdClass($instance);
$this->services['connection2'] = $instance = new \stdClass($a, $b);
$b->handler2 = new \stdClass(${($_ = isset($this->services['manager2']) ? $this->services['manager2'] : $this->getManager2Service()) && false ?: '_'});
$c = new \stdClass($instance);
$c->handler2 = new \stdClass(${($_ = isset($this->services['manager2']) ? $this->services['manager2'] : $this->getManager2Service()) && false ?: '_'});
$a->logger2 = $b;
$b->logger2 = $c;
return $instance;
}
@ -396,6 +424,16 @@ class Symfony_DI_PhpDumper_Test_Almost_Circular_Public extends Container
return $this->services['manager2'] = new \stdClass($a);
}
/**
* Gets the public 'root' shared service.
*
* @return \stdClass
*/
protected function getRootService()
{
return $this->services['root'] = new \stdClass(${($_ = isset($this->services['level2']) ? $this->services['level2'] : $this->getLevel2Service()) && false ?: '_'}, ${($_ = isset($this->services['multiuse1']) ? $this->services['multiuse1'] : ($this->services['multiuse1'] = new \stdClass())) && false ?: '_'});
}
/**
* Gets the public 'subscriber' shared service.
*
@ -403,7 +441,13 @@ class Symfony_DI_PhpDumper_Test_Almost_Circular_Public extends Container
*/
protected function getSubscriberService()
{
return $this->services['subscriber'] = new \stdClass(${($_ = isset($this->services['manager']) ? $this->services['manager'] : $this->getManagerService()) && false ?: '_'});
$a = ${($_ = isset($this->services['manager']) ? $this->services['manager'] : $this->getManagerService()) && false ?: '_'};
if (isset($this->services['subscriber'])) {
return $this->services['subscriber'];
}
return $this->services['subscriber'] = new \stdClass($a);
}
/**
@ -421,4 +465,78 @@ class Symfony_DI_PhpDumper_Test_Almost_Circular_Public extends Container
return $this->services['bar6'] = new \stdClass($a);
}
/**
* Gets the private 'level2' shared service.
*
* @return \Symfony\Component\DependencyInjection\Tests\Fixtures\FooForCircularWithAddCalls
*/
protected function getLevel2Service()
{
$this->services['level2'] = $instance = new \Symfony\Component\DependencyInjection\Tests\Fixtures\FooForCircularWithAddCalls();
$instance->call(${($_ = isset($this->services['level3']) ? $this->services['level3'] : $this->getLevel3Service()) && false ?: '_'});
return $instance;
}
/**
* Gets the private 'level3' shared service.
*
* @return \stdClass
*/
protected function getLevel3Service()
{
return $this->services['level3'] = new \stdClass(${($_ = isset($this->services['level4']) ? $this->services['level4'] : $this->getLevel4Service()) && false ?: '_'});
}
/**
* Gets the private 'level4' shared service.
*
* @return \stdClass
*/
protected function getLevel4Service()
{
return $this->services['level4'] = new \stdClass(${($_ = isset($this->services['multiuse1']) ? $this->services['multiuse1'] : ($this->services['multiuse1'] = new \stdClass())) && false ?: '_'}, ${($_ = isset($this->services['level5']) ? $this->services['level5'] : $this->getLevel5Service()) && false ?: '_'});
}
/**
* Gets the private 'level5' shared service.
*
* @return \stdClass
*/
protected function getLevel5Service()
{
$a = ${($_ = isset($this->services['level6']) ? $this->services['level6'] : $this->getLevel6Service()) && false ?: '_'};
if (isset($this->services['level5'])) {
return $this->services['level5'];
}
return $this->services['level5'] = new \stdClass($a);
}
/**
* Gets the private 'level6' shared service.
*
* @return \Symfony\Component\DependencyInjection\Tests\Fixtures\FooForCircularWithAddCalls
*/
protected function getLevel6Service()
{
$this->services['level6'] = $instance = new \Symfony\Component\DependencyInjection\Tests\Fixtures\FooForCircularWithAddCalls();
$instance->call(${($_ = isset($this->services['level5']) ? $this->services['level5'] : $this->getLevel5Service()) && false ?: '_'});
return $instance;
}
/**
* Gets the private 'multiuse1' shared service.
*
* @return \stdClass
*/
protected function getMultiuse1Service()
{
return $this->services['multiuse1'] = new \stdClass();
}
}

View file

@ -125,7 +125,7 @@ class ProjectServiceContainer extends Container
/**
* Computes a dynamic parameter.
*
* @param string The name of the dynamic parameter to load
* @param string $name The name of the dynamic parameter to load
*
* @return mixed The value of the dynamic parameter
*

View file

@ -104,7 +104,7 @@ class Symfony_DI_PhpDumper_Test_Base64Parameters extends Container
/**
* Computes a dynamic parameter.
*
* @param string The name of the dynamic parameter to load
* @param string $name The name of the dynamic parameter to load
*
* @return mixed The value of the dynamic parameter
*

View file

@ -81,8 +81,8 @@ class Symfony_DI_PhpDumper_Test_Deep_Graph extends Container
if (isset($this->services['foo'])) {
return $this->services['foo'];
}
$b = new \stdClass();
$c = new \stdClass();
$c->p3 = new \stdClass();

View file

@ -73,7 +73,7 @@ class ProjectServiceContainer extends Container
*/
protected function getBarService()
{
return $this->services['bar'] = new \stdClass(${($_ = isset($this->services['bar_%env(BAR)%']) ? $this->services['bar_%env(BAR)%'] : $this->services['bar_%env(BAR)%'] = new \stdClass()) && false ?: '_'});
return $this->services['bar'] = new \stdClass(${($_ = isset($this->services['bar_%env(BAR)%']) ? $this->services['bar_%env(BAR)%'] : ($this->services['bar_%env(BAR)%'] = new \stdClass())) && false ?: '_'});
}
/**
@ -83,7 +83,7 @@ class ProjectServiceContainer extends Container
*/
protected function getFooService()
{
return $this->services['foo'] = new \stdClass(${($_ = isset($this->services['bar_%env(BAR)%']) ? $this->services['bar_%env(BAR)%'] : $this->services['bar_%env(BAR)%'] = new \stdClass()) && false ?: '_'}, array('baz_'.$this->getEnv('string:BAR') => new \stdClass()));
return $this->services['foo'] = new \stdClass(${($_ = isset($this->services['bar_%env(BAR)%']) ? $this->services['bar_%env(BAR)%'] : ($this->services['bar_%env(BAR)%'] = new \stdClass())) && false ?: '_'}, array('baz_'.$this->getEnv('string:BAR') => new \stdClass()));
}
/**
@ -145,7 +145,7 @@ class ProjectServiceContainer extends Container
/**
* Computes a dynamic parameter.
*
* @param string The name of the dynamic parameter to load
* @param string $name The name of the dynamic parameter to load
*
* @return mixed The value of the dynamic parameter
*

View file

@ -110,7 +110,7 @@ class ProjectServiceContainer extends Container
include_once $this->targetDirs[1].'/includes/HotPath/C2.php';
include_once $this->targetDirs[1].'/includes/HotPath/C3.php';
return $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C2'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C2(${($_ = isset($this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C3']) ? $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C3'] : $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C3'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C3()) && false ?: '_'});
return $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C2'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C2(${($_ = isset($this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C3']) ? $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C3'] : ($this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C3'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C3())) && false ?: '_'});
}
/**
@ -174,7 +174,7 @@ class ProjectServiceContainer extends Container
/**
* Computes a dynamic parameter.
*
* @param string The name of the dynamic parameter to load
* @param string $name The name of the dynamic parameter to load
*
* @return mixed The value of the dynamic parameter
*

View file

@ -64,14 +64,14 @@ class Symfony_DI_PhpDumper_Test_Inline_Self_Ref extends Container
*/
protected function getFooService()
{
$b = new \App\Bar();
$a = new \App\Baz($b);
$a = new \App\Bar();
$this->services['App\Foo'] = $instance = new \App\Foo($a);
$b = new \App\Baz($a);
$b->bar = $a;
$b->foo = $instance;
$this->services['App\Foo'] = $instance = new \App\Foo($b);
$a->bar = $b;
$a->foo = $instance;
return $instance;
}

View file

@ -98,7 +98,7 @@ class Symfony_DI_PhpDumper_Test_Legacy_Privates extends Container
*/
protected function getBarService()
{
return $this->services['bar'] = new \stdClass(${($_ = isset($this->services['private_not_inlined']) ? $this->services['private_not_inlined'] : $this->services['private_not_inlined'] = new \stdClass()) && false ?: '_'});
return $this->services['bar'] = new \stdClass(${($_ = isset($this->services['private_not_inlined']) ? $this->services['private_not_inlined'] : ($this->services['private_not_inlined'] = new \stdClass())) && false ?: '_'});
}
/**

View file

@ -76,7 +76,7 @@ class ProjectServiceContainer extends Container
*/
protected function getBarServiceService()
{
return $this->services['bar_service'] = new \stdClass(${($_ = isset($this->services['baz_service']) ? $this->services['baz_service'] : $this->services['baz_service'] = new \stdClass()) && false ?: '_'});
return $this->services['bar_service'] = new \stdClass(${($_ = isset($this->services['baz_service']) ? $this->services['baz_service'] : ($this->services['baz_service'] = new \stdClass())) && false ?: '_'});
}
/**
@ -89,7 +89,7 @@ class ProjectServiceContainer extends Container
return $this->services['foo_service'] = new \Symfony\Component\DependencyInjection\ServiceLocator(array('bar' => function () {
return ${($_ = isset($this->services['bar_service']) ? $this->services['bar_service'] : $this->getBarServiceService()) && false ?: '_'};
}, 'baz' => function () {
$f = function (\stdClass $v) { return $v; }; return $f(${($_ = isset($this->services['baz_service']) ? $this->services['baz_service'] : $this->services['baz_service'] = new \stdClass()) && false ?: '_'});
$f = function (\stdClass $v) { return $v; }; return $f(${($_ = isset($this->services['baz_service']) ? $this->services['baz_service'] : ($this->services['baz_service'] = new \stdClass())) && false ?: '_'});
}, 'nil' => function () {
return NULL;
}));
@ -133,7 +133,7 @@ class ProjectServiceContainer extends Container
protected function getTranslator1Service()
{
return $this->services['translator_1'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\StubbedTranslator(new \Symfony\Component\DependencyInjection\ServiceLocator(array('translator.loader_1' => function () {
return ${($_ = isset($this->services['translator.loader_1']) ? $this->services['translator.loader_1'] : $this->services['translator.loader_1'] = new \stdClass()) && false ?: '_'};
return ${($_ = isset($this->services['translator.loader_1']) ? $this->services['translator.loader_1'] : ($this->services['translator.loader_1'] = new \stdClass())) && false ?: '_'};
})));
}
@ -145,10 +145,10 @@ class ProjectServiceContainer extends Container
protected function getTranslator2Service()
{
$this->services['translator_2'] = $instance = new \Symfony\Component\DependencyInjection\Tests\Fixtures\StubbedTranslator(new \Symfony\Component\DependencyInjection\ServiceLocator(array('translator.loader_2' => function () {
return ${($_ = isset($this->services['translator.loader_2']) ? $this->services['translator.loader_2'] : $this->services['translator.loader_2'] = new \stdClass()) && false ?: '_'};
return ${($_ = isset($this->services['translator.loader_2']) ? $this->services['translator.loader_2'] : ($this->services['translator.loader_2'] = new \stdClass())) && false ?: '_'};
})));
$instance->addResource('db', ${($_ = isset($this->services['translator.loader_2']) ? $this->services['translator.loader_2'] : $this->services['translator.loader_2'] = new \stdClass()) && false ?: '_'}, 'nl');
$instance->addResource('db', ${($_ = isset($this->services['translator.loader_2']) ? $this->services['translator.loader_2'] : ($this->services['translator.loader_2'] = new \stdClass())) && false ?: '_'}, 'nl');
return $instance;
}
@ -161,10 +161,10 @@ class ProjectServiceContainer extends Container
protected function getTranslator3Service()
{
$this->services['translator_3'] = $instance = new \Symfony\Component\DependencyInjection\Tests\Fixtures\StubbedTranslator(new \Symfony\Component\DependencyInjection\ServiceLocator(array('translator.loader_3' => function () {
return ${($_ = isset($this->services['translator.loader_3']) ? $this->services['translator.loader_3'] : $this->services['translator.loader_3'] = new \stdClass()) && false ?: '_'};
return ${($_ = isset($this->services['translator.loader_3']) ? $this->services['translator.loader_3'] : ($this->services['translator.loader_3'] = new \stdClass())) && false ?: '_'};
})));
$a = ${($_ = isset($this->services['translator.loader_3']) ? $this->services['translator.loader_3'] : $this->services['translator.loader_3'] = new \stdClass()) && false ?: '_'};
$a = ${($_ = isset($this->services['translator.loader_3']) ? $this->services['translator.loader_3'] : ($this->services['translator.loader_3'] = new \stdClass())) && false ?: '_'};
$instance->addResource('db', $a, 'nl');
$instance->addResource('db', $a, 'en');

View file

@ -67,7 +67,7 @@ class ProjectServiceContainer extends Container
*/
protected function getBarServiceService()
{
return $this->services['bar_service'] = new \stdClass(${($_ = isset($this->services['baz_service']) ? $this->services['baz_service'] : $this->services['baz_service'] = new \stdClass()) && false ?: '_'});
return $this->services['bar_service'] = new \stdClass(${($_ = isset($this->services['baz_service']) ? $this->services['baz_service'] : ($this->services['baz_service'] = new \stdClass())) && false ?: '_'});
}
/**
@ -77,7 +77,7 @@ class ProjectServiceContainer extends Container
*/
protected function getFooServiceService()
{
return $this->services['foo_service'] = new \stdClass(${($_ = isset($this->services['baz_service']) ? $this->services['baz_service'] : $this->services['baz_service'] = new \stdClass()) && false ?: '_'});
return $this->services['foo_service'] = new \stdClass(${($_ = isset($this->services['baz_service']) ? $this->services['baz_service'] : ($this->services['baz_service'] = new \stdClass())) && false ?: '_'});
}
/**

View file

@ -67,7 +67,7 @@ class ProjectServiceContainer extends Container
*/
protected function getPublicFooService()
{
return $this->services['public_foo'] = new \stdClass(${($_ = isset($this->services['private_foo']) ? $this->services['private_foo'] : $this->services['private_foo'] = new \stdClass()) && false ?: '_'});
return $this->services['public_foo'] = new \stdClass(${($_ = isset($this->services['private_foo']) ? $this->services['private_foo'] : ($this->services['private_foo'] = new \stdClass())) && false ?: '_'}->bar);
}
/**

View file

@ -78,7 +78,7 @@ class Symfony_DI_PhpDumper_Test_Rot13Parameters extends Container
protected function getContainer_EnvVarProcessorsLocatorService()
{
return $this->services['container.env_var_processors_locator'] = new \Symfony\Component\DependencyInjection\ServiceLocator(array('rot13' => function () {
return ${($_ = isset($this->services['Symfony\Component\DependencyInjection\Tests\Dumper\Rot13EnvVarProcessor']) ? $this->services['Symfony\Component\DependencyInjection\Tests\Dumper\Rot13EnvVarProcessor'] : $this->services['Symfony\Component\DependencyInjection\Tests\Dumper\Rot13EnvVarProcessor'] = new \Symfony\Component\DependencyInjection\Tests\Dumper\Rot13EnvVarProcessor()) && false ?: '_'};
return ${($_ = isset($this->services['Symfony\Component\DependencyInjection\Tests\Dumper\Rot13EnvVarProcessor']) ? $this->services['Symfony\Component\DependencyInjection\Tests\Dumper\Rot13EnvVarProcessor'] : ($this->services['Symfony\Component\DependencyInjection\Tests\Dumper\Rot13EnvVarProcessor'] = new \Symfony\Component\DependencyInjection\Tests\Dumper\Rot13EnvVarProcessor())) && false ?: '_'};
}));
}
@ -133,7 +133,7 @@ class Symfony_DI_PhpDumper_Test_Rot13Parameters extends Container
/**
* Computes a dynamic parameter.
*
* @param string The name of the dynamic parameter to load
* @param string $name The name of the dynamic parameter to load
*
* @return mixed The value of the dynamic parameter
*

View file

@ -84,13 +84,13 @@ class ProjectServiceContainer extends Container
protected function getFooServiceService()
{
return $this->services['foo_service'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber((new \Symfony\Component\DependencyInjection\ServiceLocator(array('Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition' => function () {
$f = function (\Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition $v = null) { return $v; }; return $f(${($_ = isset($this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition']) ? $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition'] : $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition()) && false ?: '_'});
$f = function (\Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition $v = null) { return $v; }; return $f(${($_ = isset($this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition']) ? $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition'] : ($this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition())) && false ?: '_'});
}, 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber' => function () {
$f = function (\Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber $v) { return $v; }; return $f(${($_ = isset($this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber']) ? $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber'] : $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber()) && false ?: '_'});
$f = function (\Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber $v) { return $v; }; return $f(${($_ = isset($this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber']) ? $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber'] : ($this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber())) && false ?: '_'});
}, 'bar' => function () {
$f = function (\Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition $v) { return $v; }; return $f(${($_ = isset($this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber']) ? $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber'] : $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber()) && false ?: '_'});
$f = function (\Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition $v) { return $v; }; return $f(${($_ = isset($this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber']) ? $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber'] : ($this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber())) && false ?: '_'});
}, 'baz' => function () {
$f = function (\Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition $v = null) { return $v; }; return $f(${($_ = isset($this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition']) ? $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition'] : $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition()) && false ?: '_'});
$f = function (\Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition $v = null) { return $v; }; return $f(${($_ = isset($this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition']) ? $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition'] : ($this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition())) && false ?: '_'});
})))->withContext('foo_service', $this));
}

View file

@ -67,22 +67,20 @@ class ProjectServiceContainer extends Container
{
$a = new \TSantos\Serializer\NormalizerRegistry();
$d = new \TSantos\Serializer\EventDispatcher\EventDispatcher();
$d->addSubscriber(new \TSantos\SerializerBundle\EventListener\StopwatchListener(new \Symfony\Component\Stopwatch\Stopwatch(true)));
$this->services['tsantos_serializer'] = $instance = new \TSantos\Serializer\EventEmitterSerializer(new \TSantos\Serializer\Encoder\JsonEncoder(), $a, $d);
$b = new \TSantos\Serializer\Normalizer\CollectionNormalizer();
$c = new \TSantos\Serializer\EventDispatcher\EventDispatcher();
$c->addSubscriber(new \TSantos\SerializerBundle\EventListener\StopwatchListener(new \Symfony\Component\Stopwatch\Stopwatch(true)));
$this->services['tsantos_serializer'] = $instance = new \TSantos\Serializer\EventEmitterSerializer(new \TSantos\Serializer\Encoder\JsonEncoder(), $a, $c);
$b->setSerializer($instance);
$c = new \TSantos\Serializer\Normalizer\JsonNormalizer();
$c->setSerializer($instance);
$d = new \TSantos\Serializer\Normalizer\JsonNormalizer();
$d->setSerializer($instance);
$a->add(new \TSantos\Serializer\Normalizer\ObjectNormalizer(new \TSantos\SerializerBundle\Serializer\CircularReferenceHandler()));
$a->add($b);
$a->add($c);
$a->add($d);
return $instance;
}

View file

@ -107,7 +107,7 @@ class Symfony_DI_PhpDumper_Test_Uninitialized_Reference extends Container
{
$this->services['baz'] = $instance = new \stdClass();
$instance->foo3 = ${($_ = isset($this->services['foo3']) ? $this->services['foo3'] : $this->services['foo3'] = new \stdClass()) && false ?: '_'};
$instance->foo3 = ${($_ = isset($this->services['foo3']) ? $this->services['foo3'] : ($this->services['foo3'] = new \stdClass())) && false ?: '_'};
return $instance;
}

View file

@ -58,7 +58,6 @@ class IniFileLoaderTest extends TestCase
$this->markTestSkipped(sprintf('Converting the value "%s" to "%s" is not supported by the IniFileLoader.', $key, $value));
}
$this->loader->load('types.ini');
$expected = parse_ini_file(__DIR__.'/../Fixtures/ini/types.ini', true, INI_SCANNER_TYPED);
$this->assertSame($value, $expected['parameters'][$key], '->load() converts values to PHP types');
}
@ -78,9 +77,10 @@ class IniFileLoaderTest extends TestCase
array('constant', PHP_VERSION, true),
array('12', 12, true),
array('12_string', '12', true),
array('12_quoted_number', 12, false), // INI_SCANNER_RAW removes the double quotes
array('12_comment', 12, true),
array('12_string_comment', '12', true),
array('12_string_comment_again', '12', true),
array('12_quoted_number_comment', 12, false), // INI_SCANNER_RAW removes the double quotes
array('-12', -12, true),
array('1', 1, true),
array('0', 0, true),

View file

@ -115,6 +115,20 @@ class ServiceLocatorTest extends TestCase
$subscriber->getFoo();
}
/**
* @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException
* @expectedExceptionMessage Service "foo" not found: even though it exists in the app's container, the container inside "foo" is a smaller service locator that is empty... Try using dependency injection instead.
*/
public function testGetThrowsServiceNotFoundException()
{
$container = new Container();
$container->set('foo', new \stdClass());
$locator = new ServiceLocator(array());
$locator = $locator->withContext('foo', $container);
$locator->get('foo');
}
public function testInvoke()
{
$locator = new ServiceLocator(array(

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/5.2/phpunit.xsd"
backupGlobals="false"
colors="true"
bootstrap="vendor/autoload.php"

View file

@ -443,14 +443,14 @@ class Form extends Link implements \ArrayAccess
// corresponding elements are either descendants or have a matching HTML5 form attribute
$formId = Crawler::xpathLiteral($this->node->getAttribute('id'));
$fieldNodes = $xpath->query(sprintf('descendant::input[@form=%s] | descendant::button[@form=%1$s] | descendant::textarea[@form=%1$s] | descendant::select[@form=%1$s] | //form[@id=%1$s]//input[not(@form)] | //form[@id=%1$s]//button[not(@form)] | //form[@id=%1$s]//textarea[not(@form)] | //form[@id=%1$s]//select[not(@form)]', $formId));
$fieldNodes = $xpath->query(sprintf('( descendant::input[@form=%s] | descendant::button[@form=%1$s] | descendant::textarea[@form=%1$s] | descendant::select[@form=%1$s] | //form[@id=%1$s]//input[not(@form)] | //form[@id=%1$s]//button[not(@form)] | //form[@id=%1$s]//textarea[not(@form)] | //form[@id=%1$s]//select[not(@form)] )[not(ancestor::template)]', $formId));
foreach ($fieldNodes as $node) {
$this->addField($node);
}
} else {
// do the xpath query with $this->node as the context node, to only find descendant elements
// however, descendant elements with form attribute are not part of this form
$fieldNodes = $xpath->query('descendant::input[not(@form)] | descendant::button[not(@form)] | descendant::textarea[not(@form)] | descendant::select[not(@form)]', $this->node);
$fieldNodes = $xpath->query('( descendant::input[not(@form)] | descendant::button[not(@form)] | descendant::textarea[not(@form)] | descendant::select[not(@form)] )[not(ancestor::template)]', $this->node);
foreach ($fieldNodes as $node) {
$this->addField($node);
}

View file

@ -1,4 +1,4 @@
Copyright (c) 2004-2018 Fabien Potencier
Copyright (c) 2004-2019 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View file

@ -400,6 +400,10 @@ class FormTest extends TestCase
$form = $this->createForm('<form><input type="text" name="foo" value="foo" disabled="disabled" /><input type="text" name="bar" value="bar" /><input type="submit" /></form>');
$this->assertEquals(array('bar' => 'bar'), $form->getValues(), '->getValues() does not include disabled fields');
$form = $this->createForm('<form><template><input type="text" name="foo" value="foo" /></template><input type="text" name="bar" value="bar" /><input type="submit" /></form>');
$this->assertEquals(array('bar' => 'bar'), $form->getValues(), '->getValues() does not include template fields');
$this->assertFalse($form->has('foo'));
}
public function testSetValues()
@ -450,6 +454,10 @@ class FormTest extends TestCase
$form = $this->createForm('<form method="post"><input type="file" name="foo[bar]" disabled="disabled" /><input type="submit" /></form>');
$this->assertEquals(array(), $form->getFiles(), '->getFiles() does not include disabled file fields');
$form = $this->createForm('<form method="post"><template><input type="file" name="foo"/></template><input type="text" name="bar" value="bar"/><input type="submit"/></form>');
$this->assertEquals(array(), $form->getFiles(), '->getFiles() does not include template file fields');
$this->assertFalse($form->has('foo'));
}
public function testGetPhpFiles()
@ -869,7 +877,7 @@ class FormTest extends TestCase
protected function createForm($form, $method = null, $currentUri = null)
{
$dom = new \DOMDocument();
$dom->loadHTML('<html>'.$form.'</html>');
@$dom->loadHTML('<html>'.$form.'</html>');
$xPath = new \DOMXPath($dom);
$nodes = $xPath->query('//input | //button');

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/5.2/phpunit.xsd"
backupGlobals="false"
colors="true"
bootstrap="vendor/autoload.php"

View file

@ -29,7 +29,7 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
protected $logger;
protected $stopwatch;
private $called;
private $callStack;
private $dispatcher;
private $wrappedListeners;
@ -38,7 +38,6 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
$this->dispatcher = $dispatcher;
$this->stopwatch = $stopwatch;
$this->logger = $logger;
$this->called = array();
$this->wrappedListeners = array();
}
@ -123,6 +122,10 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
*/
public function dispatch($eventName, Event $event = null)
{
if (null === $this->callStack) {
$this->callStack = new \SplObjectStorage();
}
if (null === $event) {
$event = new Event();
}
@ -132,19 +135,24 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
}
$this->preProcess($eventName);
$this->preDispatch($eventName, $event);
$e = $this->stopwatch->start($eventName, 'section');
$this->dispatcher->dispatch($eventName, $event);
if ($e->isStarted()) {
$e->stop();
try {
$this->preDispatch($eventName, $event);
try {
$e = $this->stopwatch->start($eventName, 'section');
try {
$this->dispatcher->dispatch($eventName, $event);
} finally {
if ($e->isStarted()) {
$e->stop();
}
}
} finally {
$this->postDispatch($eventName, $event);
}
} finally {
$this->postProcess($eventName);
}
$this->postDispatch($eventName, $event);
$this->postProcess($eventName);
return $event;
}
@ -153,11 +161,15 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
*/
public function getCalledListeners()
{
if (null === $this->callStack) {
return array();
}
$called = array();
foreach ($this->called as $eventName => $listeners) {
foreach ($listeners as $listener) {
$called[$eventName.'.'.$listener->getPretty()] = $listener->getInfo($eventName);
}
foreach ($this->callStack as $listener) {
list($eventName) = $this->callStack->getInfo();
$called[] = $listener->getInfo($eventName);
}
return $called;
@ -183,9 +195,9 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
foreach ($allListeners as $eventName => $listeners) {
foreach ($listeners as $listener) {
$called = false;
if (isset($this->called[$eventName])) {
foreach ($this->called[$eventName] as $l) {
if ($l->getWrappedListener() === $listener) {
if (null !== $this->callStack) {
foreach ($this->callStack as $calledListener) {
if ($calledListener->getWrappedListener() === $listener) {
$called = true;
break;
@ -197,19 +209,19 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
if (!$listener instanceof WrappedListener) {
$listener = new WrappedListener($listener, null, $this->stopwatch, $this);
}
$notCalled[$eventName.'.'.$listener->getPretty()] = $listener->getInfo($eventName);
$notCalled[] = $listener->getInfo($eventName);
}
}
}
uasort($notCalled, array($this, 'sortListenersByPriority'));
uasort($notCalled, array($this, 'sortNotCalledListeners'));
return $notCalled;
}
public function reset()
{
$this->called = array();
$this->callStack = null;
}
/**
@ -249,10 +261,11 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
{
foreach ($this->dispatcher->getListeners($eventName) as $listener) {
$priority = $this->getListenerPriority($eventName, $listener);
$wrappedListener = new WrappedListener($listener, null, $this->stopwatch, $this);
$wrappedListener = new WrappedListener($listener instanceof WrappedListener ? $listener->getWrappedListener() : $listener, null, $this->stopwatch, $this);
$this->wrappedListeners[$eventName][] = $wrappedListener;
$this->dispatcher->removeListener($eventName, $listener);
$this->dispatcher->addListener($eventName, $wrappedListener, $priority);
$this->callStack->attach($wrappedListener, array($eventName));
}
}
@ -281,8 +294,8 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
if (!isset($this->called[$eventName])) {
$this->called[$eventName] = new \SplObjectStorage();
}
$this->called[$eventName]->attach($listener);
} else {
$this->callStack->detach($listener);
}
if (null !== $this->logger && $skipped) {
@ -299,8 +312,12 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
}
}
private function sortListenersByPriority($a, $b)
private function sortNotCalledListeners(array $a, array $b)
{
if (0 !== $cmp = strcmp($a['event'], $b['event'])) {
return $cmp;
}
if (\is_int($a['priority']) && !\is_int($b['priority'])) {
return 1;
}

View file

@ -34,7 +34,6 @@ class WrappedListener
public function __construct($listener, $name, Stopwatch $stopwatch, EventDispatcherInterface $dispatcher = null)
{
$this->listener = $listener;
$this->name = $name;
$this->stopwatch = $stopwatch;
$this->dispatcher = $dispatcher;
$this->called = false;
@ -44,7 +43,15 @@ class WrappedListener
$this->name = \is_object($listener[0]) ? \get_class($listener[0]) : $listener[0];
$this->pretty = $this->name.'::'.$listener[1];
} elseif ($listener instanceof \Closure) {
$this->pretty = $this->name = 'closure';
$r = new \ReflectionFunction($listener);
if (false !== strpos($r->name, '{closure}')) {
$this->pretty = $this->name = 'closure';
} elseif ($class = $r->getClosureScopeClass()) {
$this->name = $class->name;
$this->pretty = $this->name.'::'.$r->name;
} else {
$this->pretty = $this->name = $r->name;
}
} elseif (\is_string($listener)) {
$this->pretty = $this->name = $listener;
} else {

View file

@ -23,11 +23,11 @@ interface EventDispatcherInterface
/**
* Dispatches an event to all registered listeners.
*
* @param string $eventName The name of the event to dispatch. The name of
* the event is the name of the method that is
* invoked on listeners.
* @param Event $event The event to pass to the event handlers/listeners
* If not supplied, an empty Event instance is created
* @param string $eventName The name of the event to dispatch. The name of
* the event is the name of the method that is
* invoked on listeners.
* @param Event|null $event The event to pass to the event handlers/listeners
* If not supplied, an empty Event instance is created
*
* @return Event
*/
@ -46,7 +46,7 @@ interface EventDispatcherInterface
/**
* Adds an event subscriber.
*
* The subscriber is asked for all the events he is
* The subscriber is asked for all the events it is
* interested in and added as a listener for these events.
*/
public function addSubscriber(EventSubscriberInterface $subscriber);
@ -64,7 +64,7 @@ interface EventDispatcherInterface
/**
* Gets the listeners of a specific event or all listeners sorted by descending priority.
*
* @param string $eventName The name of the event
* @param string|null $eventName The name of the event
*
* @return array The event listeners for the specified event, or all event listeners by event name
*/
@ -85,7 +85,7 @@ interface EventDispatcherInterface
/**
* Checks whether an event has any registered listeners.
*
* @param string $eventName The name of the event
* @param string|null $eventName The name of the event
*
* @return bool true if the specified event has any listeners, false otherwise
*/

View file

@ -12,7 +12,7 @@
namespace Symfony\Component\EventDispatcher;
/**
* An EventSubscriber knows himself what events he is interested in.
* An EventSubscriber knows itself what events it is interested in.
* If an EventSubscriber is added to an EventDispatcherInterface, the manager invokes
* {@link getSubscribedEvents} and registers the subscriber as a listener for all
* returned events.

View file

@ -38,7 +38,7 @@ class GenericEvent extends Event implements \ArrayAccess, \IteratorAggregate
/**
* Getter for subject property.
*
* @return mixed $subject The observer subject
* @return mixed The observer subject
*/
public function getSubject()
{

View file

@ -1,4 +1,4 @@
Copyright (c) 2004-2018 Fabien Potencier
Copyright (c) 2004-2019 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View file

@ -426,7 +426,7 @@ class TestEventSubscriberWithPriorities implements EventSubscriberInterface
return array(
'pre.foo' => array('preFoo', 10),
'post.foo' => array('postFoo'),
);
);
}
}

View file

@ -110,17 +110,17 @@ class TraceableEventDispatcherTest extends TestCase
$tdispatcher->addListener('foo', function () {}, 5);
$listeners = $tdispatcher->getNotCalledListeners();
$this->assertArrayHasKey('stub', $listeners['foo.closure']);
unset($listeners['foo.closure']['stub']);
$this->assertArrayHasKey('stub', $listeners[0]);
unset($listeners[0]['stub']);
$this->assertEquals(array(), $tdispatcher->getCalledListeners());
$this->assertEquals(array('foo.closure' => array('event' => 'foo', 'pretty' => 'closure', 'priority' => 5)), $listeners);
$this->assertEquals(array(array('event' => 'foo', 'pretty' => 'closure', 'priority' => 5)), $listeners);
$tdispatcher->dispatch('foo');
$listeners = $tdispatcher->getCalledListeners();
$this->assertArrayHasKey('stub', $listeners['foo.closure']);
unset($listeners['foo.closure']['stub']);
$this->assertEquals(array('foo.closure' => array('event' => 'foo', 'pretty' => 'closure', 'priority' => 5)), $listeners);
$this->assertArrayHasKey('stub', $listeners[0]);
unset($listeners[0]['stub']);
$this->assertEquals(array(array('event' => 'foo', 'pretty' => 'closure', 'priority' => 5)), $listeners);
$this->assertEquals(array(), $tdispatcher->getNotCalledListeners());
}
@ -133,10 +133,22 @@ class TraceableEventDispatcherTest extends TestCase
$tdispatcher->reset();
$listeners = $tdispatcher->getNotCalledListeners();
$this->assertArrayHasKey('stub', $listeners['foo.closure']);
unset($listeners['foo.closure']['stub']);
$this->assertArrayHasKey('stub', $listeners[0]);
unset($listeners[0]['stub']);
$this->assertEquals(array(), $tdispatcher->getCalledListeners());
$this->assertEquals(array('foo.closure' => array('event' => 'foo', 'pretty' => 'closure', 'priority' => 5)), $listeners);
$this->assertEquals(array(array('event' => 'foo', 'pretty' => 'closure', 'priority' => 5)), $listeners);
}
public function testDispatchAfterReset()
{
$tdispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch());
$tdispatcher->addListener('foo', function () {}, 5);
$tdispatcher->reset();
$tdispatcher->dispatch('foo');
$listeners = $tdispatcher->getCalledListeners();
$this->assertArrayHasKey('stub', $listeners[0]);
}
public function testGetCalledListenersNested()

View file

@ -0,0 +1,64 @@
<?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\EventDispatcher\Tests\Debug;
use PHPUnit\Framework\TestCase;
use Symfony\Component\EventDispatcher\Debug\WrappedListener;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Stopwatch\Stopwatch;
class WrappedListenerTest extends TestCase
{
/**
* @dataProvider provideListenersToDescribe
*/
public function testListenerDescription(callable $listener, $expected)
{
$wrappedListener = new WrappedListener($listener, null, $this->getMockBuilder(Stopwatch::class)->getMock(), $this->getMockBuilder(EventDispatcherInterface::class)->getMock());
$this->assertStringMatchesFormat($expected, $wrappedListener->getPretty());
}
public function provideListenersToDescribe()
{
$listeners = array(
array(new FooListener(), 'Symfony\Component\EventDispatcher\Tests\Debug\FooListener::__invoke'),
array(array(new FooListener(), 'listen'), 'Symfony\Component\EventDispatcher\Tests\Debug\FooListener::listen'),
array(array('Symfony\Component\EventDispatcher\Tests\Debug\FooListener', 'listenStatic'), 'Symfony\Component\EventDispatcher\Tests\Debug\FooListener::listenStatic'),
array('var_dump', 'var_dump'),
array(function () {}, 'closure'),
);
if (\PHP_VERSION_ID >= 70100) {
$listeners[] = array(\Closure::fromCallable(array(new FooListener(), 'listen')), 'Symfony\Component\EventDispatcher\Tests\Debug\FooListener::listen');
$listeners[] = array(\Closure::fromCallable(array('Symfony\Component\EventDispatcher\Tests\Debug\FooListener', 'listenStatic')), 'Symfony\Component\EventDispatcher\Tests\Debug\FooListener::listenStatic');
$listeners[] = array(\Closure::fromCallable(function () {}), 'closure');
}
return $listeners;
}
}
class FooListener
{
public function listen()
{
}
public function __invoke()
{
}
public static function listenStatic()
{
}
}

Some files were not shown because too many files have changed in this diff Show more