8000 Move deprecations to the DebugClassLoader · symfony/symfony@c27904c · GitHub
[go: up one dir, main page]

Skip to content

Commit c27904c

Browse files
committed
Move deprecations to the DebugClassLoader
1 parent 9403988 commit c27904c

File tree

7 files changed

+72
-41
lines changed

7 files changed

+72
-41
lines changed

src/Symfony/Component/Debug/DebugClassLoader.php

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class DebugClassLoader
2828
private $isFinder;
2929
private static $caseCheck;
3030
private static $deprecated = array();
31+
private static $final = array();
3132
private static $php7Reserved = array('int', 'float', 'bool', 'string', 'true', 'false', 'null');
3233
private static $darwinCache = array('/' => array('/', array()));
3334

@@ -165,9 +166,18 @@ public function loadClass($class)
165166

166167
if (in_array(strtolower($refl->getShortName()), self::$php7Reserved)) {
167168
@trigger_error(sprintf('%s uses a reserved class name (%s) that will break on PHP 7 and higher', $name, $refl->getShortName()), E_USER_DEPRECATED);
168-
} elseif (preg_match('#\n \* @deprecated (.*?)\r?\n \*(?: @|/$)#s', $refl->getDocComment(), $notice)) {
169+
}
170+
171+
if (preg_match('#\n \* @final( .*)?\r?\n \*(?: @|/$)#s', $refl->getDocComment())) {
172+
self::$final[$name] = true;
173+
}
174+
175+
if (preg_match('#\n \* @deprecated (.*?)\r?\n \*(?: @|/$)#s', $refl->getDocComment(), $notice)) {
169176
self::$deprecated[$name] = preg_replace('#\s*\r?\n \* +#', ' ', $notice[1]);
170177
} else {
178+
// Trigger deprecations for deprecated and final parents
179+
// only if the class is not deprecated itself
180+
171181
if (2 > $len = 1 + (strpos($name, '\\', 1 + strpos($name, '\\')) ?: strpos($name, '_'))) {
172182
$len = 0;
173183
$ns = '';
@@ -187,6 +197,9 @@ public function loadClass($class)
187197
if ($parent && isset(self::$deprecated[$parent]) && strncmp($ns, $parent, $len)) {
188198
@trigger_error(sprintf('The %s class extends %s that is deprecated %s', $name, $parent, self::$deprecated[$parent]), E_USER_DEPRECATED);
189199
}
200+
if ($parent && isset(self::$final[$parent]) && strncmp($ns, $parent, $len)) {
201+
@trigger_error(sprintf('Extending the class %s in %s is deprecated and may break in a future major release.', $parent, $name), E_USER_DEPRECATED);
202+
}
190203

191204
$parentInterfaces = array();
192205
$deprecatedInterfaces = array();

src/Symfony/Component/Debug/Tests/DebugClassLoaderTest.php

Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@
1111

1212
namespace Symfony\Component\Debug\Tests;
1313

14+
use Symfony\Component\ClassLoader\MapClassLoader;
1415
use Symfony\Component\Debug\DebugClassLoader;
1516
use Symfony\Component\Debug\ErrorHandler;
17+
use Symfony\Component\Debug\Tests\Fixtures;
1618

1719
class DebugClassLoaderTest extends \PHPUnit_Framework_TestCase
1820
{
@@ -267,39 +269,62 @@ class_exists('Test\\'.__NAMESPACE__.'\\Float', true);
267269

268270
$this->assertSame($xError, $lastError);
269271
}
272+
273+
public function testExtendedFinalClass()
274+
{
275+
set_error_handler(function () { return false; });
276+
$e = error_reporting(0);
277+
trigger_error('', E_USER_NOTICE);
278+
279+
class_exists('Test\\'.__NAMESPACE__.'\\ExtendsFinalClass', true);
280+
281+
error_reporting($e);
282+
restore_error_handler();
283+
284+
$lastError = error_get_last();
285+
unset($lastError['file'], $lastError['line']);
286+
287+
$xError = array(
288+
'type' => E_USER_DEPRECATED,
289+
'message' => sprintf('Extending the class %s in Test\Symfony\Component\Debug\Tests\ExtendsFinalClass is deprecated and may break in the next major release.', Fixtures\FinalClass::class),
290+
);
291+
292+
$this->assertSame($xError, $lastError);
293+
}
270294
}
271295

272296
class ClassLoader
273297
{
274-
public function loadClass($class)
298+
private $mapLoader;
299+
300+
public function __construct()
275301
{
302+
$map = array(
303+
Fixtures\CaseMismatch::class => 'CaseMismatch.php',
304+
Fixtures\Psr4CaseMismatch::class => 'psr4'.DIRECTORY_SEPARATOR.'Psr4CaseMismatch.php',
305+
Fixtures\NotPSR0::class => 'reallyNotPsr0.php',
306+
Fixtures\NotPSR0bis::class => 'notPsr0Bis.php',
307+
Fixtures\DeprecatedInterface::class => 'DeprecatedInterface.php',
308+
Fixtures\FinalClass::class => 'FinalClass.php',
309+
);
310+
array_walk($map, function (&$file) {
311+
$file = __DIR__.DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR.$file;
312+
});
313+
$this->mapLoader = new MapClassLoader($map);
276314
}
277315

278-
public function getClassMap()
316+
public function loadClass($class)
279317
{
280-
return array(__NAMESPACE__.'\Fixtures\NotPSR0bis' => __DIR__.'/Fixtures/notPsr0Bis.php');
281318
}
282319

283320
public function findFile($class)
284321
{
285-
$fixtureDir = __DIR__.DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR;
286-
287322
if (__NAMESPACE__.'\TestingUnsilencing' === $class) {
288323
eval('-- parse error --');
289324
} elseif (__NAMESPACE__.'\TestingStacking' === $class) {
290325
eval('namespace '.__NAMESPACE__.'; class TestingStacking { function foo() {} }');
291326
} elseif (__NAMESPACE__.'\TestingCaseMismatch' === $class) {
292327
eval('namespace '.__NAMESPACE__.'; class TestingCaseMisMatch {}');
293-
} elseif (__NAMESPACE__.'\Fixtures\CaseMismatch' === $class) {
294-
return $fixtureDir.'CaseMismatch.php';
295-
} elseif (__NAMESPACE__.'\Fixtures\Psr4CaseMismatch' === $class) {
296-
return $fixtureDir.'psr4'.DIRECTORY_SEPARATOR.'Psr4CaseMismatch.php';
297-
} elseif (__NAMESPACE__.'\Fixtures\NotPSR0' === $class) {
298-
return $fixtureDir.'reallyNotPsr0.php';
299-
} elseif (__NAMESPACE__.'\Fixtures\NotPSR0bis' === $class) {
300-
return $fixtureDir.'notPsr0Bis.php';
301-
} elseif (__NAMESPACE__.'\Fixtures\DeprecatedInterface' === $class) {
302-
return $fixtureDir.'DeprecatedInterface.php';
303328
} elseif ('Symfony\Bridge\Debug\Tests\Fixtures\ExtendsDeprecatedParent' === $class) {
304329
eval('namespace Symfony\Bridge\Debug\Tests\Fixtures; class ExtendsDeprecatedParent extends \\'.__NAMESPACE__.'\Fixtures\DeprecatedClass {}');
305330
} elseif ('Test\\'.__NAMESPACE__.'\DeprecatedParentClass' === $class) {
@@ -310,6 +335,10 @@ public function findFile($class)
310335
eval('namespace Test\\'.__NAMESPACE__.'; class NonDeprecatedInterfaceClass implements \\'.__NAMESPACE__.'\Fixtures\NonDeprecatedInterface {}');
311336
} elseif ('Test\\'.__NAMESPACE__.'\Float' === $class) {
312337
eval('namespace Test\\'.__NAMESPACE__.'; class Float {}');
338+
} elseif ('Test\\'.__NAMESPACE__.'\ExtendsFinalClass' === $class) {
339+
eval('namespace Test\\'.__NAMESPACE__.'; class ExtendsFinalClass extends \\'.__NAMESPACE__.'\Fixtures\FinalClass {}');
340+
} else {
341+
return $this->mapLoader->findFile($class);
313342
}
314343
}
315344
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace Symfony\Component\Debug\Tests\Fixtures;
4+
5+
/**
6+
* @final
7+
*/
8+
class FinalClass
9+
{
10+
}

src/Symfony/Component/Serializer/Encoder/ChainDecoder.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
* @author Jordi Boggiano <j.boggiano@seld.be>
2020
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
2121
* @author Lukas Kahwe Smith <smith@pooteeweet.org>
22+
*
23+
* @final
2224
*/
2325
class ChainDecoder implements DecoderInterface
2426
{
@@ -28,10 +30,6 @@ class ChainDecoder implements DecoderInterface
2830
public function __construct(array $decoders = array())
2931
{
3032
$this->decoders = $decoders;
31-
32-
if (__CLASS__ !== get_class($this)) {
33-
@trigger_error(sprintf('Extending %s is deprecated since 3.3 and won\'t be supported in 4.0 as it will be final.', __CLASS__), E_USER_DEPRECATED);
34-
}
3533
}
3634

3735
/**

src/Symfony/Component/Serializer/Encoder/ChainEncoder.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
* @author Jordi Boggiano <j.boggiano@seld.be>
2020
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
2121
* @author Lukas Kahwe Smith <smith@pooteeweet.org>
22+
*
23+
* @final
2224
*/
2325
class ChainEncoder implements EncoderInterface
2426
{
@@ -28,10 +30,6 @@ class ChainEncoder implements EncoderInterface
2830
public function __construct(array $encoders = array())
2931
{
3032
$this->encoders = $encoders;
31-
32-
if (__CLASS__ !== get_class($this)) {
33-
@trigger_error(sprintf('Extending %s is deprecated since 3.3 and won\'t be supported in 4.0 as it will be final.', __CLASS__), E_USER_DEPRECATED);
34-
}
3533
}
3634

3735
/**

src/Symfony/Component/Serializer/Tests/Encoder/ChainDecoderTest.php

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -74,17 +74,4 @@ public function testDecodeUnsupportedFormat()
7474
{
7575
$this->chainDecoder->decode('string_to_decode', self::FORMAT_3);
7676
}
77-
78-
/**
79-
* @group legacy
80-
* @expectedDeprecation Extending Symfony\Component\Serializer\Encoder\ChainDecoder is deprecated %s.
81-
*/
82-
public function testExtendDeprecation()
83-
{
84-
new ExtendedChainDecoder();
85-
}
86-
}
87-
88-
class ExtendedChainDecoder extends ChainDecoder
89-
{
9077
}

src/Symfony/Component/Serializer/Tests/Encoder/ChainEncoderTest.php

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,3 @@ public function supportsEncoding($format)
127127
return true;
128128
}
129129
}
130-
131-
class ExtendedChainEncoder extends ChainEncoder
132-
{
133-
}

0 commit comments

Comments
 (0)
0