From d638237f098af218c150abd070e30ab9075f7724 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 9 Sep 2018 11:07:24 +0200 Subject: [PATCH] [Debug] fix detecting overriden final/internal methods implemented using traits --- .../Component/Debug/DebugClassLoader.php | 20 +++++++++---------- .../Debug/Tests/DebugClassLoaderTest.php | 15 ++++++-------- .../Tests/Fixtures/ExtendedFinalMethod.php | 2 ++ .../Debug/Tests/Fixtures/FinalMethod.php | 7 +++++++ .../Tests/Fixtures/FinalMethod2Trait.php | 10 ++++++++++ .../Debug/Tests/phpt/debug_class_loader.phpt | 1 + 6 files changed, 35 insertions(+), 20 deletions(-) create mode 100644 src/Symfony/Component/Debug/Tests/Fixtures/FinalMethod2Trait.php diff --git a/src/Symfony/Component/Debug/DebugClassLoader.php b/src/Symfony/Component/Debug/DebugClassLoader.php index dff57e69bd..32cbd31607 100644 --- a/src/Symfony/Component/Debug/DebugClassLoader.php +++ b/src/Symfony/Component/Debug/DebugClassLoader.php @@ -247,25 +247,23 @@ class DebugClassLoader continue; } - // Method from a trait - if ($method->getFilename() !== $refl->getFileName()) { - continue; - } - if ($isClass && $parent && isset(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); } - foreach ($parentAndTraits as $use) { - if (isset(self::$internalMethods[$use][$method->name])) { - list($declaringClass, $message) = self::$internalMethods[$use][$method->name]; - 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); - } + if (isset(self::$internalMethods[$name][$method->name])) { + list($declaringClass, $message) = self::$internalMethods[$name][$method->name]; + 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); } } + // Method from a trait + if ($method->getFilename() !== $refl->getFileName()) { + continue; + } + // Detect method annotations if (false === $doc = $method->getDocComment()) { continue; diff --git a/src/Symfony/Component/Debug/Tests/DebugClassLoaderTest.php b/src/Symfony/Component/Debug/Tests/DebugClassLoaderTest.php index 0219f53350..cd89c06e58 100644 --- a/src/Symfony/Component/Debug/Tests/DebugClassLoaderTest.php +++ b/src/Symfony/Component/Debug/Tests/DebugClassLoaderTest.php @@ -312,24 +312,21 @@ class DebugClassLoaderTest extends TestCase public function testExtendedFinalMethod() { - set_error_handler(function () { return false; }); - $e = error_reporting(0); - trigger_error('', E_USER_NOTICE); + $deprecations = array(); + set_error_handler(function ($type, $msg) use (&$deprecations) { $deprecations[] = $msg; }); + $e = error_reporting(E_USER_DEPRECATED); class_exists(__NAMESPACE__.'\\Fixtures\\ExtendedFinalMethod', true); error_reporting($e); restore_error_handler(); - $lastError = error_get_last(); - unset($lastError['file'], $lastError['line']); - $xError = array( - 'type' => E_USER_DEPRECATED, - '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::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() diff --git a/src/Symfony/Component/Debug/Tests/Fixtures/ExtendedFinalMethod.php b/src/Symfony/Component/Debug/Tests/Fixtures/ExtendedFinalMethod.php index 2bd337e5a2..050d19ff5e 100644 --- a/src/Symfony/Component/Debug/Tests/Fixtures/ExtendedFinalMethod.php +++ b/src/Symfony/Component/Debug/Tests/Fixtures/ExtendedFinalMethod.php @@ -4,6 +4,8 @@ namespace Symfony\Component\Debug\Tests\Fixtures; class ExtendedFinalMethod extends FinalMethod { + use FinalMethod2Trait; + /** * {@inheritdoc} */ diff --git a/src/Symfony/Component/Debug/Tests/Fixtures/FinalMethod.php b/src/Symfony/Component/Debug/Tests/Fixtures/FinalMethod.php index 92ec421863..98a47524c4 100644 --- a/src/Symfony/Component/Debug/Tests/Fixtures/FinalMethod.php +++ b/src/Symfony/Component/Debug/Tests/Fixtures/FinalMethod.php @@ -11,6 +11,13 @@ class FinalMethod { } + /** + * @final + */ + public function finalMethod2() + { + } + public function anotherMethod() { } diff --git a/src/Symfony/Component/Debug/Tests/Fixtures/FinalMethod2Trait.php b/src/Symfony/Component/Debug/Tests/Fixtures/FinalMethod2Trait.php new file mode 100644 index 0000000000..8547f3afed --- /dev/null +++ b/src/Symfony/Component/Debug/Tests/Fixtures/FinalMethod2Trait.php @@ -0,0 +1,10 @@ + --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::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".