@@ -51,7 +51,7 @@ public function build(ConfigurationInterface $configuration): \Closure
5151 $ this ->classes = [];
5252
5353 $ rootNode = $ configuration ->getConfigTreeBuilder ()->buildTree ();
54- $ rootClass = new ClassBuilder ('Symfony \\Config ' , $ rootNode ->getName (), $ rootNode );
54+ $ rootClass = new ClassBuilder ('Symfony \\Config ' , $ rootNode ->getName (), $ rootNode, true );
5555
5656 $ path = $ this ->getFullPath ($ rootClass );
5757 if (!is_file ($ path )) {
@@ -68,7 +68,7 @@ public function NAME(): string
6868 $ this ->writeClasses ();
6969 }
7070
71- return function () use ($ path , $ rootClass ) {
71+ return static function () use ($ path , $ rootClass ) {
7272 require_once $ path ;
7373 $ className = $ rootClass ->getFqcn ();
7474
@@ -94,6 +94,9 @@ private function writeClasses(): void
9494 if ($ class ->getProperties ()) {
9595 $ class ->addProperty ('_usedProperties ' , null , '[] ' );
9696 }
97+ if ($ class ->isRoot ) {
98+ $ class ->addProperty ('_hasDeprecatedCalls ' , null , 'false ' );
99+ }
97100 $ this ->buildSetExtraKey ($ class );
98101
99102 file_put_contents ($ this ->getFullPath ($ class ), $ class ->build ());
@@ -134,10 +137,13 @@ private function handleArrayNode(ArrayNode $node, ClassBuilder $class, string $n
134137 if ($ acceptScalar ) {
135138 $ comment = \sprintf (" * @template TValue of %s \n * @param TValue \$value \n%s " , $ paramType , $ comment );
136139 $ comment .= \sprintf (' * @return %s|$this ' ."\n" , $ childClass ->getFqcn ());
137- $ comment .= \sprintf (' * @psalm-return (TValue is array ? %s : static) ' ."\n " , $ childClass ->getFqcn ());
140+ $ comment .= \sprintf (' * @psalm-return (TValue is array ? %s : static) ' ."\n" , $ childClass ->getFqcn ());
141+ }
142+ if ($ class ->isRoot ) {
143+ $ comment .= " * @deprecated since Symfony 7.4 \n" ;
138144 }
139145 if ('' !== $ comment ) {
140- $ comment = "/** \n$ comment*/ \n" ;
146+ $ comment = "/** \n$ comment */ \n" ;
141147 }
142148
143149 $ property = $ class ->addProperty (
@@ -146,7 +152,7 @@ private function handleArrayNode(ArrayNode $node, ClassBuilder $class, string $n
146152 );
147153 $ body = $ acceptScalar ? '
148154COMMENTpublic function NAME(PARAM_TYPE $value = []): CLASS|static
149- {
155+ {DEPRECATED_BODY
150156 if (!\is_array($value)) {
151157 $this->_usedProperties[ \'PROPERTY \'] = true;
152158 $this->PROPERTY = $value;
@@ -164,7 +170,7 @@ private function handleArrayNode(ArrayNode $node, ClassBuilder $class, string $n
164170 return $this->PROPERTY;
165171} ' : '
166172COMMENTpublic function NAME(array $value = []): CLASS
167- {
173+ {DEPRECATED_BODY
168174 if (null === $this->PROPERTY) {
169175 $this->_usedProperties[ \'PROPERTY \'] = true;
170176 $this->PROPERTY = new CLASS($value);
@@ -176,6 +182,7 @@ private function handleArrayNode(ArrayNode $node, ClassBuilder $class, string $n
176182} ' ;
177183 $ class ->addUse (InvalidConfigurationException::class);
178184 $ class ->addMethod ($ node ->getName (), $ body , [
185+ 'DEPRECATED_BODY ' => $ class ->isRoot ? "\n \$this->_hasDeprecatedCalls = true; " : '' ,
179186 'COMMENT ' => $ comment ,
180187 'PROPERTY ' => $ property ->getName (),
181188 'CLASS ' => $ childClass ->getFqcn (),
@@ -195,15 +202,17 @@ private function handleVariableNode(VariableNode $node, ClassBuilder $class): vo
195202/**
196203COMMENT *
197204 * @return $this
198- */
205+ *DEPRECATED_ANNOTATION /
199206public function NAME(mixed $valueDEFAULT): static
200- {
207+ {DEPRECATED_BODY
201208 $this->_usedProperties[ \'PROPERTY \'] = true;
202209 $this->PROPERTY = $value;
203210
204211 return $this;
205212} ' ;
206213 $ class ->addMethod ($ node ->getName (), $ body , [
214+ 'DEPRECATED_BODY ' => $ class ->isRoot ? "\n \$this->_hasDeprecatedCalls = true; " : '' ,
215+ 'DEPRECATED_ANNOTATION ' => $ class ->isRoot ? " @deprecated since Symfony 7.4 \n * " : '' ,
207216 'PROPERTY ' => $ property ->getName (),
208217 'COMMENT ' => $ comment ,
209218 'DEFAULT ' => $ node ->hasDefaultValue () ? ' = ' .var_export ($ node ->getDefaultValue (), true ) : '' ,
@@ -232,16 +241,18 @@ private function handlePrototypedArrayNode(PrototypedArrayNode $node, ClassBuild
232241 * @param ParamConfigurator|list<ParamConfigurator|PROTOTYPE_TYPE>EXTRA_TYPE $value
233242 *
234243 * @return $this
235- */
244+ *DEPRECATED_ANNOTATION /
236245public function NAME(PARAM_TYPE $value): static
237- {
246+ {DEPRECATED_BODY
238247 $this->_usedProperties[ \'PROPERTY \'] = true;
239248 $this->PROPERTY = $value;
240249
241250 return $this;
242251} ' ;
243252
244253 $ class ->addMethod ($ node ->getName (), $ body , [
254+ 'DEPRECATED_BODY ' => $ class ->isRoot ? "\n \$this->_hasDeprecatedCalls = true; " : '' ,
255+ 'DEPRECATED_ANNOTATION ' => $ class ->isRoot ? " @deprecated since Symfony 7.4 \n * " : '' ,
245256 'PROPERTY ' => $ property ->getName (),
246257 'PROTOTYPE_TYPE ' => implode ('| ' , $ prototypeParameterTypes ),
247258 'EXTRA_TYPE ' => $ nodeTypesWithoutArray ? '| ' .implode ('| ' , $ nodeTypesWithoutArray ) : '' ,
@@ -251,16 +262,18 @@ public function NAME(PARAM_TYPE $value): static
251262 $ body = '
252263/**
253264 * @return $this
254- */
265+ *DEPRECATED_ANNOTATION /
255266public function NAME(string $VAR, TYPE $VALUE): static
256- {
267+ {DEPRECATED_BODY
257268 $this->_usedProperties[ \'PROPERTY \'] = true;
258269 $this->PROPERTY[$VAR] = $VALUE;
259270
260271 return $this;
261272} ' ;
262273
263274 $ class ->addMethod ($ methodName , $ body , [
275+ 'DEPRECATED_BODY ' => $ class ->isRoot ? "\n \$this->_hasDeprecatedCalls = true; " : '' ,
276+ 'DEPRECATED_ANNOTATION ' => $ class ->isRoot ? " @deprecated since Symfony 7.4 \n * " : '' ,
264277 'PROPERTY ' => $ property ->getName (),
265278 'TYPE ' => ['mixed ' ] !== $ prototypeParameterTypes ? 'ParamConfigurator| ' .implode ('| ' , $ prototypeParameterTypes ) : 'mixed ' ,
266279 'VAR ' => '' === $ key ? 'key ' : $ key ,
@@ -290,16 +303,19 @@ public function NAME(string $VAR, TYPE $VALUE): static
290303 if ($ acceptScalar ) {
291304 $ comment = \sprintf (" * @template TValue of %s \n * @param TValue \$value \n%s " , $ paramType , $ comment );
292305 $ comment .= \sprintf (' * @return %s|$this ' ."\n" , $ childClass ->getFqcn ());
293- $ comment .= \sprintf (' * @psalm-return (TValue is array ? %s : static) ' ."\n " , $ childClass ->getFqcn ());
306+ $ comment .= \sprintf (' * @psalm-return (TValue is array ? %s : static) ' ."\n" , $ childClass ->getFqcn ());
307+ }
308+ if ($ class ->isRoot ) {
309+ $ comment .= " * @deprecated since Symfony 7.4 \n" ;
294310 }
295311 if ('' !== $ comment ) {
296- $ comment = "/** \n$ comment*/ \n" ;
312+ $ comment = "/** \n$ comment */ \n" ;
297313 }
298314
299315 if ($ noKey ) {
300316 $ body = $ acceptScalar ? '
301317COMMENTpublic function NAME(PARAM_TYPE $value = []): CLASS|static
302- {
318+ {DEPRECATED_BODY
303319 $this->_usedProperties[ \'PROPERTY \'] = true;
304320 if (!\is_array($value)) {
305321 $this->PROPERTY[] = $value;
@@ -310,12 +326,13 @@ public function NAME(string $VAR, TYPE $VALUE): static
310326 return $this->PROPERTY[] = new CLASS($value);
311327} ' : '
312328COMMENTpublic function NAME(array $value = []): CLASS
313- {
329+ {DEPRECATED_BODY
314330 $this->_usedProperties[ \'PROPERTY \'] = true;
315331
316332 return $this->PROPERTY[] = new CLASS($value);
317333} ' ;
318334 $ class ->addMethod ($ methodName , $ body , [
335+ 'DEPRECATED_BODY ' => $ class ->isRoot ? "\n \$this->_hasDeprecatedCalls = true; " : '' ,
319336 'COMMENT ' => $ comment ,
320337 'PROPERTY ' => $ property ->getName (),
321338 'CLASS ' => $ childClass ->getFqcn (),
@@ -324,7 +341,7 @@ public function NAME(string $VAR, TYPE $VALUE): static
324341 } else {
325342 $ body = $ acceptScalar ? '
326343COMMENTpublic function NAME(string $VAR, PARAM_TYPE $VALUE = []): CLASS|static
327- {
344+ {DEPRECATED_BODY
328345 if (!\is_array($VALUE)) {
329346 $this->_usedProperties[ \'PROPERTY \'] = true;
330347 $this->PROPERTY[$VAR] = $VALUE;
@@ -342,7 +359,7 @@ public function NAME(string $VAR, TYPE $VALUE): static
342359 return $this->PROPERTY[$VAR];
343360} ' : '
344361COMMENTpublic function NAME(string $VAR, array $VALUE = []): CLASS
345- {
362+ {DEPRECATED_BODY
346363 if (!isset($this->PROPERTY[$VAR])) {
347364 $this->_usedProperties[ \'PROPERTY \'] = true;
348365 $this->PROPERTY[$VAR] = new CLASS($VALUE);
@@ -354,7 +371,9 @@ public function NAME(string $VAR, TYPE $VALUE): static
354371} ' ;
355372 $ class ->addUse (InvalidConfigurationException::class);
356373 $ class ->addMethod ($ methodName , str_replace ('$value ' , '$VAR ' , $ body ), [
357- 'COMMENT ' => $ comment , 'PROPERTY ' => $ property ->getName (),
374+ 'DEPRECATED_BODY ' => $ class ->isRoot ? "\n \$this->_hasDeprecatedCalls = true; " : '' ,
375+ 'COMMENT ' => $ comment ,
376+ 'PROPERTY ' => $ property ->getName (),
358377 'CLASS ' => $ childClass ->getFqcn (),
359378 'VAR ' => '' === $ key ? 'key ' : $ key ,
360379 'VALUE ' => 'value ' === $ key ? 'data ' : 'value ' ,
@@ -374,16 +393,21 @@ private function handleScalarNode(ScalarNode $node, ClassBuilder $class): void
374393 $ body = '
375394/**
376395COMMENT * @return $this
377- */
396+ *DEPRECATED_ANNOTATION /
378397public function NAME($value): static
379- {
398+ {DEPRECATED_BODY
380399 $this->_usedProperties[ \'PROPERTY \'] = true;
381400 $this->PROPERTY = $value;
382401
383402 return $this;
384403} ' ;
385404
386- $ class ->addMethod ($ node ->getName (), $ body , ['PROPERTY ' => $ property ->getName (), 'COMMENT ' => $ comment ]);
405+ $ class ->addMethod ($ node ->getName (), $ body , [
406+ 'DEPRECATED_BODY ' => $ class ->isRoot ? "\n \$this->_hasDeprecatedCalls = true; " : '' ,
407+ 'DEPRECATED_ANNOTATION ' => $ class ->isRoot ? " @deprecated since Symfony 7.4 \n * " : '' ,
408+ 'PROPERTY ' => $ property ->getName (),
409+ 'COMMENT ' => $ comment ,
410+ ]);
387411 }
388412
389413 private function getParameterTypes (NodeInterface $ node ): array
@@ -509,6 +533,13 @@ private function buildToArray(ClassBuilder $class): void
509533
510534 $ extraKeys = $ class ->shouldAllowExtraKeys () ? ' + $this->_extraKeys ' : '' ;
511535
536+ if ($ class ->isRoot ) {
537+ $ body .= "
538+ if ( \$this->_hasDeprecatedCalls) {
539+ trigger_deprecation('symfony/config', '7.4', 'Calling any fluent method on \"%s \" is deprecated; pass the configuration to the constructor instead.', \$this::class);
540+ } " ;
541+ }
542+
512543 $ class ->addMethod ('toArray ' , '
513544public function NAME(): array
514545{
@@ -583,13 +614,16 @@ private function buildSetExtraKey(ClassBuilder $class): void
583614 * @param ParamConfigurator|mixed $value
584615 *
585616 * @return $this
586- */
617+ *DEPRECATED_ANNOTATION /
587618public function NAME(string $key, mixed $value): static
588- {
619+ {DEPRECATED_BODY
589620 $this->_extraKeys[$key] = $value;
590621
591622 return $this;
592- } ' );
623+ } ' , [
624+ 'DEPRECATED_BODY ' => $ class ->isRoot ? "\n \$this->_hasDeprecatedCalls = true; " : '' ,
625+ 'DEPRECATED_ANNOTATION ' => $ class ->isRoot ? " @deprecated since Symfony 7.4 \n * " : '' ,
626+ ]);
593627 }
594628
595629 private function getSubNamespace (ClassBuilder $ rootClass ): string
0 commit comments