[Debug][DebugClassLoader] Match more cases for final, deprecated and internal classes / methods extends
This commit is contained in:
parent
e231edd5dc
commit
c3b670a908
@ -233,8 +233,8 @@ class DebugClassLoader
|
|||||||
// Detect annotations on the class
|
// Detect annotations on the class
|
||||||
if (false !== $doc = $refl->getDocComment()) {
|
if (false !== $doc = $refl->getDocComment()) {
|
||||||
foreach (['final', 'deprecated', 'internal'] as $annotation) {
|
foreach (['final', 'deprecated', 'internal'] as $annotation) {
|
||||||
if (false !== \strpos($doc, $annotation) && preg_match('#\n \* @'.$annotation.'(?:( .+?)\.?)?\r?\n \*(?: @|/$)#s', $doc, $notice)) {
|
if (false !== \strpos($doc, $annotation) && preg_match('#\n\s+\* @'.$annotation.'(?:( .+?)\.?)?\r?\n\s+\*(?: @|/$)#s', $doc, $notice)) {
|
||||||
self::${$annotation}[$class] = isset($notice[1]) ? preg_replace('#\s*\r?\n \* +#', ' ', $notice[1]) : '';
|
self::${$annotation}[$class] = isset($notice[1]) ? preg_replace('#\.?\r?\n( \*)? *(?= |\r?\n|$)#', '', $notice[1]) : '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -308,7 +308,7 @@ class DebugClassLoader
|
|||||||
|
|
||||||
foreach (['final', 'internal'] as $annotation) {
|
foreach (['final', 'internal'] as $annotation) {
|
||||||
if (false !== \strpos($doc, $annotation) && preg_match('#\n\s+\* @'.$annotation.'(?:( .+?)\.?)?\r?\n\s+\*(?: @|/$)#s', $doc, $notice)) {
|
if (false !== \strpos($doc, $annotation) && preg_match('#\n\s+\* @'.$annotation.'(?:( .+?)\.?)?\r?\n\s+\*(?: @|/$)#s', $doc, $notice)) {
|
||||||
$message = isset($notice[1]) ? preg_replace('#\s*\r?\n \* +#', ' ', $notice[1]) : '';
|
$message = isset($notice[1]) ? preg_replace('#\.?\r?\n( \*)? *(?= |\r?\n|$)#', '', $notice[1]) : '';
|
||||||
self::${$annotation.'Methods'}[$class][$method->name] = [$class, $message];
|
self::${$annotation.'Methods'}[$class][$method->name] = [$class, $message];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -290,24 +290,31 @@ class DebugClassLoaderTest extends TestCase
|
|||||||
|
|
||||||
public function testExtendedFinalClass()
|
public function testExtendedFinalClass()
|
||||||
{
|
{
|
||||||
set_error_handler(function () { return false; });
|
$deprecations = [];
|
||||||
$e = error_reporting(0);
|
set_error_handler(function ($type, $msg) use (&$deprecations) { $deprecations[] = $msg; });
|
||||||
trigger_error('', E_USER_NOTICE);
|
$e = error_reporting(E_USER_DEPRECATED);
|
||||||
|
|
||||||
class_exists('Test\\'.__NAMESPACE__.'\\ExtendsFinalClass', true);
|
require __DIR__.'/Fixtures/FinalClasses.php';
|
||||||
|
|
||||||
|
$i = 1;
|
||||||
|
while(class_exists($finalClass = __NAMESPACE__.'\\Fixtures\\FinalClass'.$i++, false)) {
|
||||||
|
spl_autoload_call($finalClass);
|
||||||
|
class_exists('Test\\'.__NAMESPACE__.'\\Extends'.substr($finalClass, strrpos($finalClass, '\\') + 1), true);
|
||||||
|
}
|
||||||
|
|
||||||
error_reporting($e);
|
error_reporting($e);
|
||||||
restore_error_handler();
|
restore_error_handler();
|
||||||
|
|
||||||
$lastError = error_get_last();
|
$this->assertSame([
|
||||||
unset($lastError['file'], $lastError['line']);
|
'The "Symfony\Component\Debug\Tests\Fixtures\FinalClass1" class is considered final since version 3.3. It may change without further notice as of its next major version. You should not extend it from "Test\Symfony\Component\Debug\Tests\ExtendsFinalClass1".',
|
||||||
|
'The "Symfony\Component\Debug\Tests\Fixtures\FinalClass2" class is considered final. It may change without further notice as of its next major version. You should not extend it from "Test\Symfony\Component\Debug\Tests\ExtendsFinalClass2".',
|
||||||
$xError = [
|
'The "Symfony\Component\Debug\Tests\Fixtures\FinalClass3" class is considered final comment with @@@ and ***. It may change without further notice as of its next major version. You should not extend it from "Test\Symfony\Component\Debug\Tests\ExtendsFinalClass3".',
|
||||||
'type' => E_USER_DEPRECATED,
|
'The "Symfony\Component\Debug\Tests\Fixtures\FinalClass4" class is considered final. It may change without further notice as of its next major version. You should not extend it from "Test\Symfony\Component\Debug\Tests\ExtendsFinalClass4".',
|
||||||
'message' => 'The "Symfony\Component\Debug\Tests\Fixtures\FinalClass" class is considered final since version 3.3. It may change without further notice as of its next major version. You should not extend it from "Test\Symfony\Component\Debug\Tests\ExtendsFinalClass".',
|
'The "Symfony\Component\Debug\Tests\Fixtures\FinalClass5" class is considered final multiline comment. It may change without further notice as of its next major version. You should not extend it from "Test\Symfony\Component\Debug\Tests\ExtendsFinalClass5".',
|
||||||
];
|
'The "Symfony\Component\Debug\Tests\Fixtures\FinalClass6" class is considered final. It may change without further notice as of its next major version. You should not extend it from "Test\Symfony\Component\Debug\Tests\ExtendsFinalClass6".',
|
||||||
|
'The "Symfony\Component\Debug\Tests\Fixtures\FinalClass7" class is considered final another multiline comment... It may change without further notice as of its next major version. You should not extend it from "Test\Symfony\Component\Debug\Tests\ExtendsFinalClass7".',
|
||||||
$this->assertSame($xError, $lastError);
|
'The "Symfony\Component\Debug\Tests\Fixtures\FinalClass8" class is considered final. It may change without further notice as of its next major version. You should not extend it from "Test\Symfony\Component\Debug\Tests\ExtendsFinalClass8".',
|
||||||
|
], $deprecations);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testExtendedFinalMethod()
|
public function testExtendedFinalMethod()
|
||||||
@ -417,8 +424,9 @@ class ClassLoader
|
|||||||
eval('namespace Test\\'.__NAMESPACE__.'; class NonDeprecatedInterfaceClass implements \\'.__NAMESPACE__.'\Fixtures\NonDeprecatedInterface {}');
|
eval('namespace Test\\'.__NAMESPACE__.'; class NonDeprecatedInterfaceClass implements \\'.__NAMESPACE__.'\Fixtures\NonDeprecatedInterface {}');
|
||||||
} elseif ('Test\\'.__NAMESPACE__.'\Float' === $class) {
|
} elseif ('Test\\'.__NAMESPACE__.'\Float' === $class) {
|
||||||
eval('namespace Test\\'.__NAMESPACE__.'; class Float {}');
|
eval('namespace Test\\'.__NAMESPACE__.'; class Float {}');
|
||||||
} elseif ('Test\\'.__NAMESPACE__.'\ExtendsFinalClass' === $class) {
|
} elseif (0 === strpos($class, 'Test\\'.__NAMESPACE__.'\ExtendsFinalClass')) {
|
||||||
eval('namespace Test\\'.__NAMESPACE__.'; class ExtendsFinalClass extends \\'.__NAMESPACE__.'\Fixtures\FinalClass {}');
|
$classShortName = substr($class, strrpos($class, '\\') + 1);
|
||||||
|
eval('namespace Test\\'.__NAMESPACE__.'; class '.$classShortName.' extends \\'.__NAMESPACE__.'\Fixtures\\'.substr($classShortName, 7).' {}');
|
||||||
} elseif ('Test\\'.__NAMESPACE__.'\ExtendsAnnotatedClass' === $class) {
|
} elseif ('Test\\'.__NAMESPACE__.'\ExtendsAnnotatedClass' === $class) {
|
||||||
eval('namespace Test\\'.__NAMESPACE__.'; class ExtendsAnnotatedClass extends \\'.__NAMESPACE__.'\Fixtures\AnnotatedClass {
|
eval('namespace Test\\'.__NAMESPACE__.'; class ExtendsAnnotatedClass extends \\'.__NAMESPACE__.'\Fixtures\AnnotatedClass {
|
||||||
public function deprecatedMethod() { }
|
public function deprecatedMethod() { }
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Symfony\Component\Debug\Tests\Fixtures;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @final since version 3.3.
|
|
||||||
*/
|
|
||||||
class FinalClass
|
|
||||||
{
|
|
||||||
}
|
|
84
src/Symfony/Component/Debug/Tests/Fixtures/FinalClasses.php
Normal file
84
src/Symfony/Component/Debug/Tests/Fixtures/FinalClasses.php
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Symfony\Component\Debug\Tests\Fixtures;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @final since version 3.3.
|
||||||
|
*/
|
||||||
|
class FinalClass1
|
||||||
|
{
|
||||||
|
// simple comment
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @final
|
||||||
|
*/
|
||||||
|
class FinalClass2
|
||||||
|
{
|
||||||
|
// no comment
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @final comment with @@@ and ***
|
||||||
|
*
|
||||||
|
* @author John Doe
|
||||||
|
*/
|
||||||
|
class FinalClass3
|
||||||
|
{
|
||||||
|
// with comment and a tag after
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @final
|
||||||
|
* @author John Doe
|
||||||
|
*/
|
||||||
|
class FinalClass4
|
||||||
|
{
|
||||||
|
// without comment and a tag after
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author John Doe
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @final multiline
|
||||||
|
* comment
|
||||||
|
*/
|
||||||
|
class FinalClass5
|
||||||
|
{
|
||||||
|
// with comment and a tag before
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author John Doe
|
||||||
|
*
|
||||||
|
* @final
|
||||||
|
*/
|
||||||
|
class FinalClass6
|
||||||
|
{
|
||||||
|
// without comment and a tag before
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author John Doe
|
||||||
|
*
|
||||||
|
* @final another
|
||||||
|
*
|
||||||
|
* multiline comment...
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
class FinalClass7
|
||||||
|
{
|
||||||
|
// with comment and a tag before and after
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author John Doe
|
||||||
|
* @final
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
class FinalClass8
|
||||||
|
{
|
||||||
|
// without comment and a tag before and after
|
||||||
|
}
|
Reference in New Issue
Block a user