diff --git a/src/Symfony/Bridge/Doctrine/Form/ChoiceList/IdReader.php b/src/Symfony/Bridge/Doctrine/Form/ChoiceList/IdReader.php index cd966ea986f79..4140629d934b6 100644 --- a/src/Symfony/Bridge/Doctrine/Form/ChoiceList/IdReader.php +++ b/src/Symfony/Bridge/Doctrine/Form/ChoiceList/IdReader.php @@ -20,7 +20,7 @@ * * @author Bernhard Schussek * - * @internal This class is meant for internal use only. + * @internal */ class IdReader { diff --git a/src/Symfony/Component/Debug/DebugClassLoader.php b/src/Symfony/Component/Debug/DebugClassLoader.php index 2b13c02cf92c5..43ab3a78bf551 100644 --- a/src/Symfony/Component/Debug/DebugClassLoader.php +++ b/src/Symfony/Component/Debug/DebugClassLoader.php @@ -27,6 +27,7 @@ class DebugClassLoader private $classLoader; private $isFinder; private static $caseCheck; + private static $internal = array(); private static $final = array(); private static $finalMethods = array(); private static $deprecated = array(); @@ -166,10 +167,14 @@ public function loadClass($class) } $parent = get_parent_class($class); + $doc = $refl->getDocComment(); + if (preg_match('#\n \* @internal(?:( .+?)\.?)?\r?\n \*(?: @|/$)#s', $doc, $notice)) { + self::$internal[$name] = isset($notice[1]) ? preg_replace('#\s*\r?\n \* +#', ' ', $notice[1]) : ''; + } // Not an interface nor a trait if (class_exists($name, false)) { - if (preg_match('#\n \* @final(?:( .+?)\.?)?\r?\n \*(?: @|/$)#s', $refl->getDocComment(), $notice)) { + if (preg_match('#\n \* @final(?:( .+?)\.?)?\r?\n \*(?: @|/$)#s', $doc, $notice)) { self::$final[$name] = isset($notice[1]) ? preg_replace('#\s*\r?\n \* +#', ' ', $notice[1]) : ''; } @@ -203,50 +208,57 @@ public function loadClass($class) if (in_array(strtolower($refl->getShortName()), self::$php7Reserved)) { @trigger_error(sprintf('The "%s" class uses the reserved name "%s", it will break on PHP 7 and higher', $name, $refl->getShortName()), E_USER_DEPRECATED); - } elseif (preg_match('#\n \* @deprecated (.*?)\r?\n \*(?: @|/$)#s', $refl->getDocComment(), $notice)) { + } + if (preg_match('#\n \* @deprecated (.*?)\r?\n \*(?: @|/$)#s', $refl->getDocComment(), $notice)) { self::$deprecated[$name] = preg_replace('#\s*\r?\n \* +#', ' ', $notice[1]); + } + + // Don't trigger deprecations for classes in the same vendor + if (2 > $len = 1 + (strpos($name, '\\', 1 + strpos($name, '\\')) ?: strpos($name, '_'))) { + $len = 0; + $ns = ''; } else { - // Don't trigger deprecations for classes in the same vendor - if (2 > $len = 1 + (strpos($name, '\\', 1 + strpos($name, '\\')) ?: strpos($name, '_'))) { - $len = 0; - $ns = ''; - } else { - switch ($ns = substr($name, 0, $len)) { - case 'Symfony\Bridge\\': - case 'Symfony\Bundle\\': - case 'Symfony\Component\\': - $ns = 'Symfony\\'; - $len = strlen($ns); - break; - } + switch ($ns = substr($name, 0, $len)) { + case 'Symfony\Bridge\\': + case 'Symfony\Bundle\\': + case 'Symfony\Component\\': + $ns = 'Symfony\\'; + $len = strlen($ns); + break; } + } - if (!$parent || strncmp($ns, $parent, $len)) { - if ($parent && isset(self::$deprecated[$parent]) && strncmp($ns, $parent, $len)) { - @trigger_error(sprintf('The "%s" class extends "%s" that is deprecated %s', $name, $parent, self::$deprecated[$parent]), E_USER_DEPRECATED); - } + foreach (array_merge(array($parent), class_implements($name, false), class_uses($name, false)) as $use) { + if (isset(self::$internal[$use]) && strncmp($ns, $use, $len)) { + @trigger_error(sprintf('The "%s" %s is considered internal%s. It may change without further notice. You should not use it from "%s".', $use, class_exists($use, false) ? 'class' : (interface_exists($use, false) ? 'interface' : 'trait'), self::$internal[$use], $name), E_USER_DEPRECATED); + } + } - $parentInterfaces = array(); - $deprecatedInterfaces = array(); - if ($parent) { - foreach (class_implements($parent) as $interface) { - $parentInterfaces[$interface] = 1; - } + if (!$parent || strncmp($ns, $parent, $len)) { + if ($parent && isset(self::$deprecated[$parent]) && strncmp($ns, $parent, $len)) { + @trigger_error(sprintf('The "%s" class extends "%s" that is deprecated %s', $name, $parent, self::$deprecated[$parent]), E_USER_DEPRECATED); + } + + $parentInterfaces = array(); + $deprecatedInterfaces = array(); + if ($parent) { + foreach (class_implements($parent) as $interface) { + $parentInterfaces[$interface] = 1; } + } - foreach ($refl->getInterfaceNames() as $interface) { - if (isset(self::$deprecated[$interface]) && strncmp($ns, $interface, $len)) { - $deprecatedInterfaces[] = $interface; - } - foreach (class_implements($interface) as $interface) { - $parentInterfaces[$interface] = 1; - } + foreach ($refl->getInterfaceNames() as $interface) { + if (isset(self::$deprecated[$interface]) && strncmp($ns, $interface, $len)) { + $deprecatedInterfaces[] = $interface; + } + foreach (class_implements($interface) as $interface) { + $parentInterfaces[$interface] = 1; } + } - foreach ($deprecatedInterfaces as $interface) { - if (!isset($parentInterfaces[$interface])) { - @trigger_error(sprintf('The "%s" %s "%s" that is deprecated %s', $name, $refl->isInterface() ? 'interface extends' : 'class implements', $interface, self::$deprecated[$interface]), E_USER_DEPRECATED); - } + foreach ($deprecatedInterfaces as $interface) { + if (!isset($parentInterfaces[$interface])) { + @trigger_error(sprintf('The "%s" %s "%s" that is deprecated %s', $name, $refl->isInterface() ? 'interface extends' : 'class implements', $interface, self::$deprecated[$interface]), E_USER_DEPRECATED); } } } diff --git a/src/Symfony/Component/Debug/Tests/DebugClassLoaderTest.php b/src/Symfony/Component/Debug/Tests/DebugClassLoaderTest.php index f1e3fb7c611b5..a53c17b0e4983 100644 --- a/src/Symfony/Component/Debug/Tests/DebugClassLoaderTest.php +++ b/src/Symfony/Component/Debug/Tests/DebugClassLoaderTest.php @@ -312,6 +312,24 @@ class_exists(__NAMESPACE__.'\\Fixtures\\ExtendedFinalMethod', true); $this->assertSame($xError, $lastError); } + + public function testInternalsUse() + { + $deprecations = array(); + set_error_handler(function ($type, $msg) use (&$deprecations) { $deprecations[] = $msg; }); + $e = error_reporting(E_USER_DEPRECATED); + + class_exists('Test\\'.__NAMESPACE__.'\\ExtendsInternals', true); + + error_reporting($e); + 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\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\InternalTrait" trait is considered internal. It may change without further notice. You should not use it from "Test\Symfony\Component\Debug\Tests\ExtendsInternals".', + )); + } } class ClassLoader @@ -335,22 +353,12 @@ public function findFile($class) eval('namespace '.__NAMESPACE__.'; class TestingStacking { function foo() {} }'); } elseif (__NAMESPACE__.'\TestingCaseMismatch' === $class) { eval('namespace '.__NAMESPACE__.'; class TestingCaseMisMatch {}'); - } elseif (__NAMESPACE__.'\Fixtures\CaseMismatch' === $class) { - return $fixtureDir.'CaseMismatch.php'; } elseif (__NAMESPACE__.'\Fixtures\Psr4CaseMismatch' === $class) { return $fixtureDir.'psr4'.DIRECTORY_SEPARATOR.'Psr4CaseMismatch.php'; } elseif (__NAMESPACE__.'\Fixtures\NotPSR0' === $class) { return $fixtureDir.'reallyNotPsr0.php'; } elseif (__NAMESPACE__.'\Fixtures\NotPSR0bis' === $class) { return $fixtureDir.'notPsr0Bis.php'; - } elseif (__NAMESPACE__.'\Fixtures\DeprecatedInterface' === $class) { - return $fixtureDir.'DeprecatedInterface.php'; - } elseif (__NAMESPACE__.'\Fixtures\FinalClass' === $class) { - return $fixtureDir.'FinalClass.php'; - } elseif (__NAMESPACE__.'\Fixtures\FinalMethod' === $class) { - return $fixtureDir.'FinalMethod.php'; - } elseif (__NAMESPACE__.'\Fixtures\ExtendedFinalMethod' === $class) { - return $fixtureDir.'ExtendedFinalMethod.php'; } elseif ('Symfony\Bridge\Debug\Tests\Fixtures\ExtendsDeprecatedParent' === $class) { eval('namespace Symfony\Bridge\Debug\Tests\Fixtures; class ExtendsDeprecatedParent extends \\'.__NAMESPACE__.'\Fixtures\DeprecatedClass {}'); } elseif ('Test\\'.__NAMESPACE__.'\DeprecatedParentClass' === $class) { @@ -363,6 +371,10 @@ public function findFile($class) eval('namespace Test\\'.__NAMESPACE__.'; class Float {}'); } elseif ('Test\\'.__NAMESPACE__.'\ExtendsFinalClass' === $class) { eval('namespace Test\\'.__NAMESPACE__.'; class ExtendsFinalClass extends \\'.__NAMESPACE__.'\Fixtures\FinalClass {}'); + } elseif ('Test\\'.__NAMESPACE__.'\ExtendsInternals' === $class) { + eval('namespace Test\\'.__NAMESPACE__.'; class ExtendsInternals extends \\'.__NAMESPACE__.'\Fixtures\InternalClass implements \\'.__NAMESPACE__.'\Fixtures\InternalInterface { + use \\'.__NAMESPACE__.'\Fixtures\InternalTrait; + }'); } } } diff --git a/src/Symfony/Component/Debug/Tests/Fixtures/InternalClass.php b/src/Symfony/Component/Debug/Tests/Fixtures/InternalClass.php new file mode 100644 index 0000000000000..745fa462162f5 --- /dev/null +++ b/src/Symfony/Component/Debug/Tests/Fixtures/InternalClass.php @@ -0,0 +1,11 @@ + * - * @internal This class should be removed in Symfony 4.0. + * @internal and will be removed in Symfony 4.0. */ class ParserCacheAdapter implements CacheItemPoolInterface { diff --git a/src/Symfony/Component/Form/ChoiceList/ArrayChoiceList.php b/src/Symfony/Component/Form/ChoiceList/ArrayChoiceList.php index a7c282849263b..50658c3911f1c 100644 --- a/src/Symfony/Component/Form/ChoiceList/ArrayChoiceList.php +++ b/src/Symfony/Component/Form/ChoiceList/ArrayChoiceList.php @@ -185,7 +185,7 @@ public function getValuesForChoices(array $choices) * corresponding values * @param array $structuredValues The values indexed by the original keys * - * @internal Must not be used by user-land code + * @internal */ protected function flatten(array $choices, $value, &$choicesByValues, &$keysByValues, &$structuredValues) { diff --git a/src/Symfony/Component/Form/ChoiceList/Factory/CachingFactoryDecorator.php b/src/Symfony/Component/Form/ChoiceList/Factory/CachingFactoryDecorator.php index 6580e661d4d66..d3460ecacad94 100644 --- a/src/Symfony/Component/Form/ChoiceList/Factory/CachingFactoryDecorator.php +++ b/src/Symfony/Component/Form/ChoiceList/Factory/CachingFactoryDecorator.php @@ -48,7 +48,7 @@ class CachingFactoryDecorator implements ChoiceListFactoryInterface * * @return string The SHA-256 hash * - * @internal Should not be used by user-land code. + * @internal */ public static function generateHash($value, $namespace = '') { @@ -71,7 +71,7 @@ public static function generateHash($value, $namespace = '') * @param array $array The array to flatten * @param array $output The flattened output * - * @internal Should not be used by user-land code + * @internal */ private static function flatten(array $array, &$output) { diff --git a/src/Symfony/Component/Validator/Context/ExecutionContext.php b/src/Symfony/Component/Validator/Context/ExecutionContext.php index 1dc982c2719ff..9c50a4f0f685b 100644 --- a/src/Symfony/Component/Validator/Context/ExecutionContext.php +++ b/src/Symfony/Component/Validator/Context/ExecutionContext.php @@ -30,8 +30,7 @@ * * @see ExecutionContextInterface * - * @internal You should not instantiate or use this class. Code against - * {@link ExecutionContextInterface} instead. + * @internal since version 2.5. Code against ExecutionContextInterface instead. */ class ExecutionContext implements ExecutionContextInterface { diff --git a/src/Symfony/Component/Validator/Context/ExecutionContextFactory.php b/src/Symfony/Component/Validator/Context/ExecutionContextFactory.php index 8182c41f8c1ca..32f004b5d0e9e 100644 --- a/src/Symfony/Component/Validator/Context/ExecutionContextFactory.php +++ b/src/Symfony/Component/Validator/Context/ExecutionContextFactory.php @@ -19,8 +19,7 @@ * * @author Bernhard Schussek * - * @internal You should not instantiate or use this class. Code against - * {@link ExecutionContextFactoryInterface} instead. + * @internal version 2.5. Code against ExecutionContextFactoryInterface instead. */ class ExecutionContextFactory implements ExecutionContextFactoryInterface { diff --git a/src/Symfony/Component/Validator/Violation/ConstraintViolationBuilder.php b/src/Symfony/Component/Validator/Violation/ConstraintViolationBuilder.php index bf887a08ec2b8..ff4d295cf31ae 100644 --- a/src/Symfony/Component/Validator/Violation/ConstraintViolationBuilder.php +++ b/src/Symfony/Component/Validator/Violation/ConstraintViolationBuilder.php @@ -22,8 +22,7 @@ * * @author Bernhard Schussek * - * @internal You should not instantiate or use this class. Code against - * {@link ConstraintViolationBuilderInterface} instead. + * @internal since version 2.5. Code against ConstraintViolationBuilderInterface instead. */ class ConstraintViolationBuilder implements ConstraintViolationBuilderInterface { pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy