Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit fdc2197

Browse files
committed
Trigger a deprecation for new parameters not defined in sub classes
1 parent bc45a0e commit fdc2197

File tree

3 files changed

+77
-8
lines changed

3 files changed

+77
-8
lines changed

src/Symfony/Component/Debug/DebugClassLoader.php

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class DebugClassLoader
3434
private static $deprecated = array();
3535
private static $internal = array();
3636
private static $internalMethods = array();
37+
private static $annotatedParameters = array();
3738
private static $darwinCache = array('/' => array('/', array()));
3839

3940
public function __construct(callable $classLoader)
@@ -229,11 +230,12 @@ private function checkClass($class, $file = null)
229230
}
230231
}
231232

232-
// Inherit @final and @internal annotations for methods
233+
// Inherit @final, @internal and @param annotations for methods
233234
self::$finalMethods[$name] = array();
234235
self::$internalMethods[$name] = array();
236+
self::$annotatedParameters[$name] = array();
235237
foreach ($parentAndTraits as $use) {
236-
foreach (array('finalMethods', 'internalMethods') as $property) {
238+
foreach (array('finalMethods', 'internalMethods', 'annotatedParameters') as $property) {
237239
if (isset(self::${$property}[$use])) {
238240
self::${$property}[$name] = self::${$property}[$name] ? self::${$property}[$use] + self::${$property}[$name] : self::${$property}[$use];
239241
}
@@ -256,12 +258,21 @@ private function checkClass($class, $file = null)
256258
@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);
257259
}
258260

259-
foreach ($parentAndTraits as $use) {
260-
if (isset(self::$internalMethods[$use][$method->name])) {
261-
list($declaringClass, $message) = self::$internalMethods[$use][$method->name];
262-
if (\strncmp($ns, $declaringClass, $len)) {
263-
@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);
264-
}
261+
if (isset(self::$internalMethods[$name][$method->name])) {
262+
list($declaringClass, $message) = self::$internalMethods[$name][$method->name];
263+
if (\strncmp($ns, $declaringClass, $len)) {
264+
@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);
265+
}
266+
}
267+
268+
if (isset(self::$annotatedParameters[$name][$method->name])) {
269+
$definedParameters = array();
270+
foreach ($method->getParameters() as $parameter) {
271+
$definedParameters[$parameter->name] = true;
272+
}
273+
274+
foreach (array_diff_key(self::$annotatedParameters[$name][$method->name], $definedParameters) as $deprecation) {
275+
@trigger_error(sprintf($deprecation, $name, $method->name), E_USER_DEPRECATED);
265276
}
266277
}
267278

@@ -276,6 +287,16 @@ private function checkClass($class, $file = null)
276287
self::${$annotation.'Methods'}[$name][$method->name] = array($name, $message);
277288
}
278289
}
290+
291+
if (false !== \strpos($doc, '@param') && preg_match_all('#\n\s+\* @param ((?:[^\s]+ )?\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*))(?: .*?)?\r?\n#s', $doc, $matches, PREG_SET_ORDER)) {
292+
if (!isset(self::$annotatedParameters[$name][$method->name])) {
293+
self::$annotatedParameters[$name][$method->name] = array();
294+
}
295+
296+
foreach ($matches as list(, $parameterSignature, $parameterName)) {
297+
self::$annotatedParameters[$name][$method->name][$parameterName] = sprintf('The method "%s::%s" defines the parameter `%s`: it may be added to its signature without further notice as of its next major version.', $name, $method->name, $parameterSignature).' You should update the signature of "%s::%s".';
298+
}
299+
}
279300
}
280301
}
281302

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,20 @@ class_exists('Test\\'.__NAMESPACE__.'\\ExtendsInternals', true);
275275
'The "Symfony\Component\Debug\Tests\Fixtures\InternalTrait2::internalMethod()" method is considered internal. It may change without further notice. You should not extend it from "Test\Symfony\Component\Debug\Tests\ExtendsInternals".',
276276
));
277277
}
278+
279+
public function testExtendedMethodDefinesNewParameters()
280+
{
281+
$deprecations = array();
282+
set_error_handler(function ($type, $msg) use (&$deprecations) { $deprecations[] = $msg; });
283+
$e = error_reporting(E_USER_DEPRECATED);
284+
285+
class_exists('Test\\'.__NAMESPACE__.'\\SubClassWithAnnotatedParameters', true);
286+
287+
error_reporting($e);
288+
restore_error_handler();
289+
290+
$this->assertSame(array('The method "Symfony\Component\Debug\Tests\Fixtures\ClassWithAnnotatedParameters::quzMethod" defines the parameter `Quz $quz`: it may be added to its signature without further notice as of its next major version. You should update the signature of "Test\Symfony\Component\Debug\Tests\SubClassWithAnnotatedParameters::quzMethod".'), $deprecations);
291+
}
278292
}
279293

280294
class ClassLoader
@@ -328,6 +342,12 @@ public function internalMethod() { }
328342
}');
329343
} elseif ('Test\\'.__NAMESPACE__.'\ExtendsInternalsParent' === $class) {
330344
eval('namespace Test\\'.__NAMESPACE__.'; class ExtendsInternalsParent extends \\'.__NAMESPACE__.'\Fixtures\InternalClass implements \\'.__NAMESPACE__.'\Fixtures\InternalInterface { }');
345+
} elseif ('Test\\'.__NAMESPACE__.'\SubClassWithAnnotatedParameters' === $class) {
346+
eval('namespace Test\\'.__NAMESPACE__.'; class SubClassWithAnnotatedParameters extends \\'.__NAMESPACE__.'\Fixtures\ClassWithAnnotatedParameters {
347+
public function fooMethod(string $foo) { }
348+
public function barMethod($bar = null) { }
349+
public function quzMethod() { }
350+
}');
331351
}
332352
}
333353
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
namespace Symfony\Component\Debug\Tests\Fixtures;
4+
5+
class ClassWithAnnotatedParameters
6+
{
7+
/**
8+
* @param string $foo This is a foo parameter.
9+
*/
10+
public function fooMethod(string $foo)
11+
{
12+
}
13+
14+
/**
15+
* @param string $bar parameter not implemented yet
16+
*/
17+
public function barMethod(/** string $bar = null */)
18+
{
19+
}
20+
21+
22+
/**
23+
* @param Quz $quz parameter not implemented yet
24+
*/
25+
public function quzMethod(/** Quz $quz = null */)
26+
{
27+
}
28+
}

0 commit comments

Comments
 (0)