-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Config] deprecate tree builders without root nodes #27476
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Config] deprecate tree builders without root nodes #27476
Conversation
4e83499
to
f981459
Compare
rebase needed |
@@ -25,6 +25,7 @@ | |||
"require-dev": { | |||
"symfony/asset": "~3.4|~4.0", | |||
"symfony/browser-kit": "~3.4|~4.0", | |||
"symfony/config": "~4.2", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this can be a normal requirement instead. I don't think it is currently possible to avoid it anyway.
@@ -24,13 +24,13 @@ | |||
"twig/twig": "~1.34|~2.4" | |||
}, | |||
"require-dev": { | |||
"symfony/config": "~3.4|~4.0", | |||
"symfony/config": "~4.2", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As TwigBundle depends on it, and WebProfilerBundle depends on TwigBundle, this gets installed all the time already. I suggest making it a normal requirement instead of a conflict rule (this might even perform better in Composer, as a <4.2
conflict rule matches lots of packages)
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 with 5.0.', E_USER_DEPRECATED); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shoudln't it be in 5.0
?
@@ -41,6 +50,11 @@ public function root($name, $type = 'array', NodeBuilder $builder = null) | |||
return $this->root = $builder->node($name, $type)->setParent($this); | |||
} | |||
|
|||
public function getRootNode(): NodeDefinition |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this return type is broken when using the deprecated API and not calling ->root()
. I suggest throwing an exception with a meaningful message instead of letting PHP throw a TypeError (which will get reported as a bug in Symfony):
throw new \RuntimeException(sprintf('Calling %s before creating the root node is not supported. Migrate to the new constructor signature instead', __METHOD__));
if (null === $name) { | ||
@trigger_error('A tree builder without a root node is deprecated since Symfony 4.2 and will not be supported anymore with 5.0.', E_USER_DEPRECATED); | ||
} else { | ||
$this->root($name, $type, $builder); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we deprecate public calls to root()
as well? or is it still intended as a feature?
both the methods (root + getRootNode) can be seen confusing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not really care to be honest. Since this is a builder there may be use cases to still call root()
later. But I also see that we could probably discuss this as part of a follow up PR if you would like to open one. :)
@@ -23,6 +23,15 @@ class TreeBuilder implements NodeParentInterface | |||
protected $tree; | |||
protected $root; | |||
|
|||
public function __construct(string $name = null, string $type = 'array', NodeBuilder $builder = null) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how about ?NodeBuilder
instead ? Use a nullable typehint instead of relying on 7.0's hackish way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is nothing hackish here, optional arguments are just fit here IMHO.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not about the fact that this is optionnal or not. It's because NodeBuilder $builder = null
, instead of ?Nodebuilder $builder = null
. Yes it's one more char, but it's more pertinent. It was a hack in 7.0 to allow a null value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Taluu it's not "more pertinent", is exactly the same, meaning wise. It's not a hack at all but how the language is defined.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
<?php
interface A {
public function dummy(int $arg = null);
}
class B implements A {
public function dummy(int $arg) { }
}
Fatal error: Declaration of B::dummy(int $arg) must be compatible with A::dummy(?int $arg = NULL) in nullable.php on line 7
Note the ?
in the stack trace while it is not in the signature, it's really the same for the engine
a588420
to
9bd6ade
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
with. a minor comment
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__)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing dot at the end of the exception message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
upported, migrate
9bd6ade
to
b8e8890
Compare
(rebase needed + comment to address) |
b8e8890
to
056768d
Compare
056768d
to
c2ce153
Compare
Thank you @xabbuh. |
…abbuh) This PR was merged into the 4.2-dev branch. Discussion ---------- [Config] deprecate tree builders without root nodes | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | yes | Tests pass? | yes | Fixed tickets | | License | MIT | Doc PR | While reviewing #27472 I wondered if we really need support config trees without a root node. If we did not support it, users wouldn't create pseudo configuration classes when they were actually not needed. Commits ------- c2ce153 deprecate tree builders without root nodes
How can we now write code that works deprecation-free in both Symfony 4.1 and 4.2? The only thing I can come up with is: $treeBuilder = new TreeBuilder("my_node");
$rootNode = method_exists($treeBuilder, "getRootNode")
? $treeBuilder->getRootNode()
: $treeBuilder->root("my_node"); which is super hacky in two ways:
@xabbuh do you have a better way? |
That's indeed the way to go as long as you do not want to drop support for Symfony 4.1. |
All right. Thanks for the super fast response! 🙌 |
…ee builder (Koc) This PR was merged into the 4.2 branch. Discussion ---------- [Config] Improve PHPdoc / IDE autocomplete for config tree builder | Q | A | ------------- | --- | Branch? | 4.2 | Bug fix? | no | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | - | License | MIT | Doc PR | - follow up of #27476 and #21047 Commits ------- 21f7977 Improve PHPdoc / IDE autocomplete for config tree builder
As of Symfony 4.2, creating a config tree without a root node, is deprecated. See symfony/symfony#27476.
As of Symfony 4.2, creating a config tree without a root node, is deprecated. See symfony/symfony#27476.
While reviewing #27472 I wondered if we really need support config trees without a root node. If we did not support it, users wouldn't create pseudo configuration classes when they were actually not needed.