[Debug] fix detecting overriden final/internal methods implemented using traits

This commit is contained in:
Nicolas Grekas 2018-09-09 11:07:24 +02:00
parent 8bc014c211
commit d638237f09
6 changed files with 35 additions and 20 deletions

View File

@ -247,25 +247,23 @@ class DebugClassLoader
continue; continue;
} }
// Method from a trait
if ($method->getFilename() !== $refl->getFileName()) {
continue;
}
if ($isClass && $parent && isset(self::$finalMethods[$parent][$method->name])) { if ($isClass && $parent && isset(self::$finalMethods[$parent][$method->name])) {
list($declaringClass, $message) = self::$finalMethods[$parent][$method->name]; list($declaringClass, $message) = self::$finalMethods[$parent][$method->name];
@trigger_error(sprintf('The "%s::%s()" method is considered final%s. It may change without further notice as of its next major version. You should not extend it from "%s".', $declaringClass, $method->name, $message, $name), E_USER_DEPRECATED); @trigger_error(sprintf('The "%s::%s()" method is considered final%s. It may change without further notice as of its next major version. You should not extend it from "%s".', $declaringClass, $method->name, $message, $name), E_USER_DEPRECATED);
} }
foreach ($parentAndTraits as $use) { if (isset(self::$internalMethods[$name][$method->name])) {
if (isset(self::$internalMethods[$use][$method->name])) { list($declaringClass, $message) = self::$internalMethods[$name][$method->name];
list($declaringClass, $message) = self::$internalMethods[$use][$method->name]; if (\strncmp($ns, $declaringClass, $len)) {
if (\strncmp($ns, $declaringClass, $len)) { @trigger_error(sprintf('The "%s::%s()" method is considered internal%s. It may change without further notice. You should not extend it from "%s".', $declaringClass, $method->name, $message, $name), E_USER_DEPRECATED);
@trigger_error(sprintf('The "%s::%s()" method is considered internal%s. It may change without further notice. You should not extend it from "%s".', $declaringClass, $method->name, $message, $name), E_USER_DEPRECATED);
}
} }
} }
// Method from a trait
if ($method->getFilename() !== $refl->getFileName()) {
continue;
}
// Detect method annotations // Detect method annotations
if (false === $doc = $method->getDocComment()) { if (false === $doc = $method->getDocComment()) {
continue; continue;

View File

@ -312,24 +312,21 @@ class DebugClassLoaderTest extends TestCase
public function testExtendedFinalMethod() public function testExtendedFinalMethod()
{ {
set_error_handler(function () { return false; }); $deprecations = array();
$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(__NAMESPACE__.'\\Fixtures\\ExtendedFinalMethod', true); class_exists(__NAMESPACE__.'\\Fixtures\\ExtendedFinalMethod', true);
error_reporting($e); error_reporting($e);
restore_error_handler(); restore_error_handler();
$lastError = error_get_last();
unset($lastError['file'], $lastError['line']);
$xError = array( $xError = array(
'type' => E_USER_DEPRECATED, 'The "Symfony\Component\Debug\Tests\Fixtures\FinalMethod::finalMethod()" method 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 "Symfony\Component\Debug\Tests\Fixtures\ExtendedFinalMethod".',
'message' => 'The "Symfony\Component\Debug\Tests\Fixtures\FinalMethod::finalMethod()" method 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 "Symfony\Component\Debug\Tests\Fixtures\ExtendedFinalMethod".', 'The "Symfony\Component\Debug\Tests\Fixtures\FinalMethod::finalMethod2()" method is considered final. It may change without further notice as of its next major version. You should not extend it from "Symfony\Component\Debug\Tests\Fixtures\ExtendedFinalMethod".',
); );
$this->assertSame($xError, $lastError); $this->assertSame($xError, $deprecations);
} }
public function testExtendedDeprecatedMethodDoesntTriggerAnyNotice() public function testExtendedDeprecatedMethodDoesntTriggerAnyNotice()

View File

@ -4,6 +4,8 @@ namespace Symfony\Component\Debug\Tests\Fixtures;
class ExtendedFinalMethod extends FinalMethod class ExtendedFinalMethod extends FinalMethod
{ {
use FinalMethod2Trait;
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */

View File

@ -11,6 +11,13 @@ class FinalMethod
{ {
} }
/**
* @final
*/
public function finalMethod2()
{
}
public function anotherMethod() public function anotherMethod()
{ {
} }

View File

@ -0,0 +1,10 @@
<?php
namespace Symfony\Component\Debug\Tests\Fixtures;
trait FinalMethod2Trait
{
public function finalMethod2()
{
}
}

View File

@ -24,3 +24,4 @@ class_exists(ExtendedFinalMethod::class);
?> ?>
--EXPECTF-- --EXPECTF--
The "Symfony\Component\Debug\Tests\Fixtures\FinalMethod::finalMethod()" method 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 "Symfony\Component\Debug\Tests\Fixtures\ExtendedFinalMethod". The "Symfony\Component\Debug\Tests\Fixtures\FinalMethod::finalMethod()" method 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 "Symfony\Component\Debug\Tests\Fixtures\ExtendedFinalMethod".
The "Symfony\Component\Debug\Tests\Fixtures\FinalMethod::finalMethod2()" method is considered final. It may change without further notice as of its next major version. You should not extend it from "Symfony\Component\Debug\Tests\Fixtures\ExtendedFinalMethod".