deprecate tree builders without root nodes

This commit is contained in:
Christian Flothmann 2018-06-02 20:20:34 +02:00
parent f065873881
commit c2ce15301c
24 changed files with 109 additions and 77 deletions

View File

@ -6,6 +6,11 @@ Cache
* Deprecated `CacheItem::getPreviousTags()`, use `CacheItem::getMetadata()` instead. * Deprecated `CacheItem::getPreviousTags()`, use `CacheItem::getMetadata()` instead.
Config
------
* Deprecated constructing a `TreeBuilder` without passing root node information.
Security Security
-------- --------

View File

@ -9,6 +9,7 @@ Cache
Config Config
------ ------
* Dropped support for constructing a `TreeBuilder` without passing root node information.
* Added the `getChildNodeDefinitions()` method to `ParentNodeDefinitionInterface`. * Added the `getChildNodeDefinitions()` method to `ParentNodeDefinitionInterface`.
* The `Processor` class has been made final * The `Processor` class has been made final

View File

@ -26,10 +26,9 @@ class Configuration implements ConfigurationInterface
*/ */
public function getConfigTreeBuilder() public function getConfigTreeBuilder()
{ {
$treeBuilder = new TreeBuilder(); $treeBuilder = new TreeBuilder('debug');
$rootNode = $treeBuilder->root('debug');
$rootNode $treeBuilder->getRootNode()
->children() ->children()
->integerNode('max_items') ->integerNode('max_items')
->info('Max number of displayed items past the first level, -1 means no limit') ->info('Max number of displayed items past the first level, -1 means no limit')

View File

@ -23,11 +23,12 @@
"symfony/var-dumper": "~4.1" "symfony/var-dumper": "~4.1"
}, },
"require-dev": { "require-dev": {
"symfony/config": "~3.4|~4.0", "symfony/config": "~4.2",
"symfony/dependency-injection": "~3.4|~4.0", "symfony/dependency-injection": "~3.4|~4.0",
"symfony/web-profiler-bundle": "~3.4|~4.0" "symfony/web-profiler-bundle": "~3.4|~4.0"
}, },
"conflict": { "conflict": {
"symfony/config": "<4.2",
"symfony/dependency-injection": "<3.4" "symfony/dependency-injection": "<3.4"
}, },
"suggest": { "suggest": {

View File

@ -54,8 +54,8 @@ class Configuration implements ConfigurationInterface
*/ */
public function getConfigTreeBuilder() public function getConfigTreeBuilder()
{ {
$treeBuilder = new TreeBuilder(); $treeBuilder = new TreeBuilder('framework');
$rootNode = $treeBuilder->root('framework'); $rootNode = $treeBuilder->getRootNode();
$rootNode $rootNode
->beforeNormalization() ->beforeNormalization()

View File

@ -25,11 +25,10 @@ class Configuration implements ConfigurationInterface
public function getConfigTreeBuilder() public function getConfigTreeBuilder()
{ {
$treeBuilder = new TreeBuilder(); $treeBuilder = new TreeBuilder('test');
$rootNode = $treeBuilder->root('test');
if ($this->customConfig) { if ($this->customConfig) {
$this->customConfig->addConfiguration($rootNode); $this->customConfig->addConfiguration($treeBuilder->getRootNode());
} }
return $treeBuilder; return $treeBuilder;

View File

@ -20,7 +20,7 @@
"ext-xml": "*", "ext-xml": "*",
"symfony/cache": "~3.4|~4.0", "symfony/cache": "~3.4|~4.0",
"symfony/dependency-injection": "^4.1.1", "symfony/dependency-injection": "^4.1.1",
"symfony/config": "~3.4|~4.0", "symfony/config": "~4.2",
"symfony/event-dispatcher": "^4.1", "symfony/event-dispatcher": "^4.1",
"symfony/http-foundation": "^4.1", "symfony/http-foundation": "^4.1",
"symfony/http-kernel": "^4.1", "symfony/http-kernel": "^4.1",

View File

@ -41,8 +41,8 @@ class MainConfiguration implements ConfigurationInterface
*/ */
public function getConfigTreeBuilder() public function getConfigTreeBuilder()
{ {
$tb = new TreeBuilder(); $tb = new TreeBuilder('security');
$rootNode = $tb->root('security'); $rootNode = $tb->getRootNode();
$rootNode $rootNode
->beforeNormalization() ->beforeNormalization()

View File

@ -18,6 +18,7 @@
"require": { "require": {
"php": "^7.1.3", "php": "^7.1.3",
"ext-xml": "*", "ext-xml": "*",
"symfony/config": "^4.2",
"symfony/security": "~4.2", "symfony/security": "~4.2",
"symfony/dependency-injection": "^3.4.3|^4.0.3", "symfony/dependency-injection": "^3.4.3|^4.0.3",
"symfony/http-kernel": "^4.1" "symfony/http-kernel": "^4.1"

View File

@ -29,8 +29,8 @@ class Configuration implements ConfigurationInterface
*/ */
public function getConfigTreeBuilder() public function getConfigTreeBuilder()
{ {
$treeBuilder = new TreeBuilder(); $treeBuilder = new TreeBuilder('twig');
$rootNode = $treeBuilder->root('twig'); $rootNode = $treeBuilder->getRootNode();
$rootNode $rootNode
->children() ->children()

View File

@ -17,7 +17,7 @@
], ],
"require": { "require": {
"php": "^7.1.3", "php": "^7.1.3",
"symfony/config": "~3.4|~4.0", "symfony/config": "~4.2",
"symfony/twig-bridge": "^3.4.3|^4.0.3", "symfony/twig-bridge": "^3.4.3|^4.0.3",
"symfony/http-foundation": "~3.4|~4.0", "symfony/http-foundation": "~3.4|~4.0",
"symfony/http-kernel": "~3.4|~4.0", "symfony/http-kernel": "~3.4|~4.0",

View File

@ -31,10 +31,9 @@ class Configuration implements ConfigurationInterface
*/ */
public function getConfigTreeBuilder() public function getConfigTreeBuilder()
{ {
$treeBuilder = new TreeBuilder(); $treeBuilder = new TreeBuilder('web_profiler');
$rootNode = $treeBuilder->root('web_profiler');
$rootNode $treeBuilder->getRootNode()
->children() ->children()
->booleanNode('toolbar')->defaultFalse()->end() ->booleanNode('toolbar')->defaultFalse()->end()
->booleanNode('intercept_redirects')->defaultFalse()->end() ->booleanNode('intercept_redirects')->defaultFalse()->end()

View File

@ -17,6 +17,7 @@
], ],
"require": { "require": {
"php": "^7.1.3", "php": "^7.1.3",
"symfony/config": "^4.2",
"symfony/http-kernel": "~4.1", "symfony/http-kernel": "~4.1",
"symfony/routing": "~3.4|~4.0", "symfony/routing": "~3.4|~4.0",
"symfony/twig-bundle": "^3.4.3|^4.0.3", "symfony/twig-bundle": "^3.4.3|^4.0.3",
@ -24,13 +25,11 @@
"twig/twig": "~1.34|~2.4" "twig/twig": "~1.34|~2.4"
}, },
"require-dev": { "require-dev": {
"symfony/config": "~3.4|~4.0",
"symfony/console": "~3.4|~4.0", "symfony/console": "~3.4|~4.0",
"symfony/dependency-injection": "~3.4|~4.0", "symfony/dependency-injection": "~3.4|~4.0",
"symfony/stopwatch": "~3.4|~4.0" "symfony/stopwatch": "~3.4|~4.0"
}, },
"conflict": { "conflict": {
"symfony/config": "<3.4",
"symfony/dependency-injection": "<3.4", "symfony/dependency-injection": "<3.4",
"symfony/event-dispatcher": "<3.4", "symfony/event-dispatcher": "<3.4",
"symfony/var-dumper": "<3.4" "symfony/var-dumper": "<3.4"

View File

@ -1,6 +1,11 @@
CHANGELOG CHANGELOG
========= =========
4.2.0
-----
* deprecated constructing a `TreeBuilder` without passing root node information
4.1.0 4.1.0
----- -----

View File

@ -24,6 +24,15 @@ class TreeBuilder implements NodeParentInterface
protected $tree; protected $tree;
protected $root; protected $root;
public function __construct(string $name = null, string $type = 'array', NodeBuilder $builder = null)
{
if (null === $name) {
@trigger_error('A tree builder without a root node is deprecated since Symfony 4.2 and will not be supported anymore in 5.0.', E_USER_DEPRECATED);
} else {
$this->root($name, $type, $builder);
}
}
/** /**
* Creates the root node. * Creates the root node.
* *
@ -42,6 +51,15 @@ class TreeBuilder implements NodeParentInterface
return $this->root = $builder->node($name, $type)->setParent($this); return $this->root = $builder->node($name, $type)->setParent($this);
} }
public function getRootNode(): NodeDefinition
{
if (null === $this->root) {
throw new \RuntimeException(sprintf('Calling %s() before creating the root node is not supported, migrate to the new constructor signature instead.', __METHOD__));
}
return $this->root;
}
/** /**
* Builds the tree. * Builds the tree.
* *

View File

@ -212,10 +212,10 @@ class ExprBuilderTest extends TestCase
*/ */
protected function getTestBuilder() protected function getTestBuilder()
{ {
$builder = new TreeBuilder(); $builder = new TreeBuilder('test');
return $builder return $builder
->root('test') ->getRootNode()
->children() ->children()
->variableNode('key') ->variableNode('key')
->validate() ->validate()

View File

@ -19,10 +19,9 @@ class TreeBuilderTest extends TestCase
{ {
public function testUsingACustomNodeBuilder() public function testUsingACustomNodeBuilder()
{ {
$builder = new TreeBuilder(); $builder = new TreeBuilder('custom', 'array', new CustomNodeBuilder());
$root = $builder->root('custom', 'array', new CustomNodeBuilder());
$nodeBuilder = $root->children(); $nodeBuilder = $builder->getRootNode()->children();
$this->assertInstanceOf('Symfony\Component\Config\Tests\Fixtures\Builder\NodeBuilder', $nodeBuilder); $this->assertInstanceOf('Symfony\Component\Config\Tests\Fixtures\Builder\NodeBuilder', $nodeBuilder);
@ -33,39 +32,36 @@ class TreeBuilderTest extends TestCase
public function testOverrideABuiltInNodeType() public function testOverrideABuiltInNodeType()
{ {
$builder = new TreeBuilder(); $builder = new TreeBuilder('override', 'array', new CustomNodeBuilder());
$root = $builder->root('override', 'array', new CustomNodeBuilder());
$definition = $root->children()->variableNode('variable'); $definition = $builder->getRootNode()->children()->variableNode('variable');
$this->assertInstanceOf('Symfony\Component\Config\Tests\Fixtures\Builder\VariableNodeDefinition', $definition); $this->assertInstanceOf('Symfony\Component\Config\Tests\Fixtures\Builder\VariableNodeDefinition', $definition);
} }
public function testAddANodeType() public function testAddANodeType()
{ {
$builder = new TreeBuilder(); $builder = new TreeBuilder('override', 'array', new CustomNodeBuilder());
$root = $builder->root('override', 'array', new CustomNodeBuilder());
$definition = $root->children()->barNode('variable'); $definition = $builder->getRootNode()->children()->barNode('variable');
$this->assertInstanceOf('Symfony\Component\Config\Tests\Fixtures\Builder\BarNodeDefinition', $definition); $this->assertInstanceOf('Symfony\Component\Config\Tests\Fixtures\Builder\BarNodeDefinition', $definition);
} }
public function testCreateABuiltInNodeTypeWithACustomNodeBuilder() public function testCreateABuiltInNodeTypeWithACustomNodeBuilder()
{ {
$builder = new TreeBuilder(); $builder = new TreeBuilder('builtin', 'array', new CustomNodeBuilder());
$root = $builder->root('builtin', 'array', new CustomNodeBuilder());
$definition = $root->children()->booleanNode('boolean'); $definition = $builder->getRootNode()->children()->booleanNode('boolean');
$this->assertInstanceOf('Symfony\Component\Config\Definition\Builder\BooleanNodeDefinition', $definition); $this->assertInstanceOf('Symfony\Component\Config\Definition\Builder\BooleanNodeDefinition', $definition);
} }
public function testPrototypedArrayNodeUseTheCustomNodeBuilder() public function testPrototypedArrayNodeUseTheCustomNodeBuilder()
{ {
$builder = new TreeBuilder(); $builder = new TreeBuilder('override', 'array', new CustomNodeBuilder());
$root = $builder->root('override', 'array', new CustomNodeBuilder());
$root = $builder->getRootNode();
$root->prototype('bar')->end(); $root->prototype('bar')->end();
$this->assertInstanceOf('Symfony\Component\Config\Tests\Fixtures\BarNode', $root->getNode(true)->getPrototype()); $this->assertInstanceOf('Symfony\Component\Config\Tests\Fixtures\BarNode', $root->getNode(true)->getPrototype());
@ -73,9 +69,9 @@ class TreeBuilderTest extends TestCase
public function testAnExtendedNodeBuilderGetsPropagatedToTheChildren() public function testAnExtendedNodeBuilderGetsPropagatedToTheChildren()
{ {
$builder = new TreeBuilder(); $builder = new TreeBuilder('propagation');
$builder->root('propagation') $builder->getRootNode()
->children() ->children()
->setNodeClass('extended', 'Symfony\Component\Config\Definition\Builder\BooleanNodeDefinition') ->setNodeClass('extended', 'Symfony\Component\Config\Definition\Builder\BooleanNodeDefinition')
->node('foo', 'extended')->end() ->node('foo', 'extended')->end()
@ -99,9 +95,9 @@ class TreeBuilderTest extends TestCase
public function testDefinitionInfoGetsTransferredToNode() public function testDefinitionInfoGetsTransferredToNode()
{ {
$builder = new TreeBuilder(); $builder = new TreeBuilder('test');
$builder->root('test')->info('root info') $builder->getRootNode()->info('root info')
->children() ->children()
->node('child', 'variable')->info('child info')->defaultValue('default') ->node('child', 'variable')->info('child info')->defaultValue('default')
->end() ->end()
@ -116,9 +112,9 @@ class TreeBuilderTest extends TestCase
public function testDefinitionExampleGetsTransferredToNode() public function testDefinitionExampleGetsTransferredToNode()
{ {
$builder = new TreeBuilder(); $builder = new TreeBuilder('test');
$builder->root('test') $builder->getRootNode()
->example(array('key' => 'value')) ->example(array('key' => 'value'))
->children() ->children()
->node('child', 'variable')->info('child info')->defaultValue('default')->example('example') ->node('child', 'variable')->info('child info')->defaultValue('default')->example('example')
@ -134,9 +130,9 @@ class TreeBuilderTest extends TestCase
public function testDefaultPathSeparatorIsDot() public function testDefaultPathSeparatorIsDot()
{ {
$builder = new TreeBuilder(); $builder = new TreeBuilder('propagation');
$builder->root('propagation') $builder->getRootNode()
->children() ->children()
->node('foo', 'variable')->end() ->node('foo', 'variable')->end()
->arrayNode('child') ->arrayNode('child')
@ -164,9 +160,9 @@ class TreeBuilderTest extends TestCase
public function testPathSeparatorIsPropagatedToChildren() public function testPathSeparatorIsPropagatedToChildren()
{ {
$builder = new TreeBuilder(); $builder = new TreeBuilder('propagation');
$builder->root('propagation') $builder->getRootNode()
->children() ->children()
->node('foo', 'variable')->end() ->node('foo', 'variable')->end()
->arrayNode('child') ->arrayNode('child')
@ -192,4 +188,13 @@ class TreeBuilderTest extends TestCase
$this->assertInstanceOf('Symfony\Component\Config\Definition\BaseNode', $childChildren['foo']); $this->assertInstanceOf('Symfony\Component\Config\Definition\BaseNode', $childChildren['foo']);
$this->assertSame('propagation/child/foo', $childChildren['foo']->getPath()); $this->assertSame('propagation/child/foo', $childChildren['foo']->getPath());
} }
/**
* @group legacy
* @expectedDeprecation A tree builder without a root node is deprecated since Symfony 4.2 and will not be supported anymore in 5.0.
*/
public function testInitializingTreeBuildersWithoutRootNode()
{
new TreeBuilder();
}
} }

View File

@ -20,9 +20,9 @@ class FinalizationTest extends TestCase
{ {
public function testUnsetKeyWithDeepHierarchy() public function testUnsetKeyWithDeepHierarchy()
{ {
$tb = new TreeBuilder(); $tb = new TreeBuilder('config', 'array');
$tree = $tb $tree = $tb
->root('config', 'array') ->getRootNode()
->children() ->children()
->node('level1', 'array') ->node('level1', 'array')
->canBeUnset() ->canBeUnset()

View File

@ -21,9 +21,9 @@ class MergeTest extends TestCase
*/ */
public function testForbiddenOverwrite() public function testForbiddenOverwrite()
{ {
$tb = new TreeBuilder(); $tb = new TreeBuilder('root', 'array');
$tree = $tb $tree = $tb
->root('root', 'array') ->getRootNode()
->children() ->children()
->node('foo', 'scalar') ->node('foo', 'scalar')
->cannotBeOverwritten() ->cannotBeOverwritten()
@ -46,9 +46,9 @@ class MergeTest extends TestCase
public function testUnsetKey() public function testUnsetKey()
{ {
$tb = new TreeBuilder(); $tb = new TreeBuilder('root', 'array');
$tree = $tb $tree = $tb
->root('root', 'array') ->getRootNode()
->children() ->children()
->node('foo', 'scalar')->end() ->node('foo', 'scalar')->end()
->node('bar', 'scalar')->end() ->node('bar', 'scalar')->end()
@ -97,9 +97,9 @@ class MergeTest extends TestCase
*/ */
public function testDoesNotAllowNewKeysInSubsequentConfigs() public function testDoesNotAllowNewKeysInSubsequentConfigs()
{ {
$tb = new TreeBuilder(); $tb = new TreeBuilder('root', 'array');
$tree = $tb $tree = $tb
->root('config', 'array') ->getRootNode()
->children() ->children()
->node('test', 'array') ->node('test', 'array')
->disallowNewKeysInSubsequentConfigs() ->disallowNewKeysInSubsequentConfigs()
@ -131,10 +131,10 @@ class MergeTest extends TestCase
public function testPerformsNoDeepMerging() public function testPerformsNoDeepMerging()
{ {
$tb = new TreeBuilder(); $tb = new TreeBuilder('root', 'array');
$tree = $tb $tree = $tb
->root('config', 'array') ->getRootNode()
->children() ->children()
->node('no_deep_merging', 'array') ->node('no_deep_merging', 'array')
->performNoDeepMerging() ->performNoDeepMerging()
@ -170,10 +170,10 @@ class MergeTest extends TestCase
public function testPrototypeWithoutAKeyAttribute() public function testPrototypeWithoutAKeyAttribute()
{ {
$tb = new TreeBuilder(); $tb = new TreeBuilder('root', 'array');
$tree = $tb $tree = $tb
->root('config', 'array') ->getRootNode()
->children() ->children()
->arrayNode('append_elements') ->arrayNode('append_elements')
->prototype('scalar')->end() ->prototype('scalar')->end()

View File

@ -22,9 +22,9 @@ class NormalizationTest extends TestCase
*/ */
public function testNormalizeEncoders($denormalized) public function testNormalizeEncoders($denormalized)
{ {
$tb = new TreeBuilder(); $tb = new TreeBuilder('root_name', 'array');
$tree = $tb $tree = $tb
->root('root_name', 'array') ->getRootNode()
->fixXmlConfig('encoder') ->fixXmlConfig('encoder')
->children() ->children()
->node('encoders', 'array') ->node('encoders', 'array')
@ -97,9 +97,9 @@ class NormalizationTest extends TestCase
*/ */
public function testAnonymousKeysArray($denormalized) public function testAnonymousKeysArray($denormalized)
{ {
$tb = new TreeBuilder(); $tb = new TreeBuilder('root', 'array');
$tree = $tb $tree = $tb
->root('root', 'array') ->getRootNode()
->children() ->children()
->node('logout', 'array') ->node('logout', 'array')
->fixXmlConfig('handler') ->fixXmlConfig('handler')
@ -186,9 +186,9 @@ class NormalizationTest extends TestCase
public function testAssociativeArrayPreserveKeys() public function testAssociativeArrayPreserveKeys()
{ {
$tb = new TreeBuilder(); $tb = new TreeBuilder('root', 'array');
$tree = $tb $tree = $tb
->root('root', 'array') ->getRootNode()
->prototype('array') ->prototype('array')
->children() ->children()
->node('foo', 'scalar')->end() ->node('foo', 'scalar')->end()
@ -210,9 +210,9 @@ class NormalizationTest extends TestCase
private function getNumericKeysTestTree() private function getNumericKeysTestTree()
{ {
$tb = new TreeBuilder(); $tb = new TreeBuilder('root', 'array');
$tree = $tb $tree = $tb
->root('root', 'array') ->getRootNode()
->children() ->children()
->node('thing', 'array') ->node('thing', 'array')
->useAttributeAsKey('id') ->useAttributeAsKey('id')

View File

@ -18,10 +18,9 @@ class ExampleConfiguration implements ConfigurationInterface
{ {
public function getConfigTreeBuilder() public function getConfigTreeBuilder()
{ {
$treeBuilder = new TreeBuilder(); $treeBuilder = new TreeBuilder('acme_root');
$rootNode = $treeBuilder->root('acme_root');
$rootNode $treeBuilder->getRootNode()
->fixXmlConfig('parameter') ->fixXmlConfig('parameter')
->fixXmlConfig('connection') ->fixXmlConfig('connection')
->fixXmlConfig('cms_page') ->fixXmlConfig('cms_page')

View File

@ -136,9 +136,8 @@ class FooConfiguration implements ConfigurationInterface
{ {
public function getConfigTreeBuilder() public function getConfigTreeBuilder()
{ {
$treeBuilder = new TreeBuilder(); $treeBuilder = new TreeBuilder('foo');
$rootNode = $treeBuilder->root('foo'); $treeBuilder->getRootNode()
$rootNode
->children() ->children()
->scalarNode('bar')->end() ->scalarNode('bar')->end()
->scalarNode('baz')->end() ->scalarNode('baz')->end()

View File

@ -223,6 +223,9 @@ class ValidateEnvPlaceholdersPassTest extends TestCase
$this->assertSame($expected, $container->resolveEnvPlaceholders($ext->getConfig())); $this->assertSame($expected, $container->resolveEnvPlaceholders($ext->getConfig()));
} }
/**
* @group legacy
*/
public function testConfigurationWithoutRootNode(): void public function testConfigurationWithoutRootNode(): void
{ {
$container = new ContainerBuilder(); $container = new ContainerBuilder();
@ -246,9 +249,8 @@ class EnvConfiguration implements ConfigurationInterface
{ {
public function getConfigTreeBuilder() public function getConfigTreeBuilder()
{ {
$treeBuilder = new TreeBuilder(); $treeBuilder = new TreeBuilder('env_extension');
$rootNode = $treeBuilder->root('env_extension'); $treeBuilder->getRootNode()
$rootNode
->children() ->children()
->scalarNode('scalar_node')->end() ->scalarNode('scalar_node')->end()
->scalarNode('scalar_node_not_empty')->cannotBeEmpty()->end() ->scalarNode('scalar_node_not_empty')->cannotBeEmpty()->end()

View File

@ -21,7 +21,7 @@
}, },
"require-dev": { "require-dev": {
"symfony/yaml": "~3.4|~4.0", "symfony/yaml": "~3.4|~4.0",
"symfony/config": "~4.1", "symfony/config": "~4.2",
"symfony/expression-language": "~3.4|~4.0" "symfony/expression-language": "~3.4|~4.0"
}, },
"suggest": { "suggest": {
@ -32,7 +32,7 @@
"symfony/proxy-manager-bridge": "Generate service proxies to lazy load them" "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them"
}, },
"conflict": { "conflict": {
"symfony/config": "<4.1.1", "symfony/config": "<4.2",
"symfony/finder": "<3.4", "symfony/finder": "<3.4",
"symfony/proxy-manager-bridge": "<3.4", "symfony/proxy-manager-bridge": "<3.4",
"symfony/yaml": "<3.4" "symfony/yaml": "<3.4"