From 08d352a302ef28b680051a39d51a58831764869e Mon Sep 17 00:00:00 2001 From: Guilhem Niot Date: Wed, 9 Aug 2017 18:49:26 +0200 Subject: [PATCH] [Debug] Correctly detect methods not from the same vendor --- .../Component/Debug/DebugClassLoader.php | 27 ++++++++++++------- .../Debug/Tests/DebugClassLoaderTest.php | 10 ++++--- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/src/Symfony/Component/Debug/DebugClassLoader.php b/src/Symfony/Component/Debug/DebugClassLoader.php index 3605868c5000..39b03cf5775d 100644 --- a/src/Symfony/Component/Debug/DebugClassLoader.php +++ b/src/Symfony/Component/Debug/DebugClassLoader.php @@ -232,19 +232,28 @@ public function loadClass($class) continue; } + // Method from a trait + if ($method->getFilename() !== $refl->getFileName()) { + continue; + } + if ($isClass && $parent && isset(self::$finalMethods[$parent][$method->name])) { - list($methodShortName, $message) = self::$finalMethods[$parent][$method->name]; - @trigger_error(sprintf('The "%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".', $methodShortName, $message, $name), E_USER_DEPRECATED); + 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::$deprecatedMethods[$use][$method->name]) && strncmp($ns, $use, $len)) { - list($methodShortName, $message) = self::$deprecatedMethods[$use][$method->name]; - @trigger_error(sprintf('The "%s" method is deprecated%s. You should not extend it from "%s".', $methodShortName, $message, $name), E_USER_DEPRECATED); + if (isset(self::$deprecatedMethods[$use][$method->name])) { + list($declaringClass, $message) = self::$deprecatedMethods[$use][$method->name]; + if (strncmp($ns, $declaringClass, $len)) { + @trigger_error(sprintf('The "%s::%s()" method is deprecated%s. You should not extend it from "%s".', $declaringClass, $method->name, $message, $name), E_USER_DEPRECATED); + } } - if (isset(self::$internalMethods[$use][$method->name]) && strncmp($ns, $use, $len)) { - list($methodShortName, $message) = self::$internalMethods[$use][$method->name]; - @trigger_error(sprintf('The "%s" method is considered internal%s. It may change without further notice. You should not use it from "%s".', $methodShortName, $message, $name), E_USER_DEPRECATED); + 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); + } } } @@ -256,7 +265,7 @@ public function loadClass($class) foreach (array('final', 'deprecated', 'internal') as $annotation) { 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]) : ''; - self::${$annotation.'Methods'}[$name][$method->name] = array(sprintf('%s::%s()', $name, $method->name), $message); + self::${$annotation.'Methods'}[$name][$method->name] = array($name, $message); } } } diff --git a/src/Symfony/Component/Debug/Tests/DebugClassLoaderTest.php b/src/Symfony/Component/Debug/Tests/DebugClassLoaderTest.php index ba83d4502db7..e83fcea770b3 100644 --- a/src/Symfony/Component/Debug/Tests/DebugClassLoaderTest.php +++ b/src/Symfony/Component/Debug/Tests/DebugClassLoaderTest.php @@ -347,10 +347,10 @@ class_exists('Test\\'.__NAMESPACE__.'\\ExtendsInternals', true); restore_error_handler(); $this->assertSame($deprecations, array( + 'The "Symfony\Component\Debug\Tests\Fixtures\InternalClass" class is considered internal since version 3.4. It may change without further notice. You should not use it from "Test\Symfony\Component\Debug\Tests\ExtendsInternalsParent".', + 'The "Symfony\Component\Debug\Tests\Fixtures\InternalInterface" interface is considered internal. It may change without further notice. You should not use it from "Test\Symfony\Component\Debug\Tests\ExtendsInternalsParent".', 'The "Symfony\Component\Debug\Tests\Fixtures\InternalTrait" trait is considered internal. It may change without further notice. You should not use it from "Test\Symfony\Component\Debug\Tests\ExtendsInternals".', - 'The "Symfony\Component\Debug\Tests\Fixtures\InternalClass" class is considered internal since version 3.4. It may change without further notice. You should not use it from "Test\Symfony\Component\Debug\Tests\ExtendsInternals".', - 'The "Symfony\Component\Debug\Tests\Fixtures\InternalInterface" interface is considered internal. It may change without further notice. You should not use it from "Test\Symfony\Component\Debug\Tests\ExtendsInternals".', - 'The "Symfony\Component\Debug\Tests\Fixtures\InternalClass::internalMethod()" method is considered internal since version 3.4. It may change without further notice. You should not use it from "Test\Symfony\Component\Debug\Tests\ExtendsInternals".', + 'The "Symfony\Component\Debug\Tests\Fixtures\InternalTrait2::internalMethod()" method is considered internal since version 3.4. It may change without further notice. You should not extend it from "Test\Symfony\Component\Debug\Tests\ExtendsInternals".', )); } } @@ -399,11 +399,13 @@ public function findFile($class) public function deprecatedMethod() { } }'); } elseif ('Test\\'.__NAMESPACE__.'\ExtendsInternals' === $class) { - eval('namespace Test\\'.__NAMESPACE__.'; class ExtendsInternals extends \\'.__NAMESPACE__.'\Fixtures\InternalClass implements \\'.__NAMESPACE__.'\Fixtures\InternalInterface { + eval('namespace Test\\'.__NAMESPACE__.'; class ExtendsInternals extends ExtendsInternalsParent { use \\'.__NAMESPACE__.'\Fixtures\InternalTrait; public function internalMethod() { } }'); + } elseif ('Test\\'.__NAMESPACE__.'\ExtendsInternalsParent' === $class) { + eval('namespace Test\\'.__NAMESPACE__.'; class ExtendsInternalsParent extends \\'.__NAMESPACE__.'\Fixtures\InternalClass implements \\'.__NAMESPACE__.'\Fixtures\InternalInterface { }'); } } }