N°8834 - Add compatibility with PHP 8.4 (#819)

* N°8834 - Add compatibility with PHP 8.4

* Rollback of scssphp/scssphp version upgrade due to compilation error
This commit is contained in:
Lenaick
2026-02-26 10:36:32 +01:00
committed by GitHub
parent d4821b7edc
commit fc967c06ce
961 changed files with 12298 additions and 7130 deletions

View File

@@ -18,8 +18,10 @@ use Mockery\MockInterface;
use Phake\IMock;
use PHPUnit\Framework\MockObject\Matcher\StatelessInvocation;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\MockObject\Stub;
use Prophecy\Prophecy\ProphecySubjectInterface;
use ProxyManager\Proxy\ProxyInterface;
use Symfony\Component\DependencyInjection\Argument\LazyClosure;
use Symfony\Component\ErrorHandler\Internal\TentativeTypes;
use Symfony\Component\VarExporter\LazyObjectInterface;
@@ -180,7 +182,7 @@ class DebugClassLoader
public static function enable(): void
{
// Ensures we don't hit https://bugs.php.net/42098
class_exists(\Symfony\Component\ErrorHandler\ErrorHandler::class);
class_exists(ErrorHandler::class);
class_exists(\Psr\Log\LogLevel::class);
if (!\is_array($functions = spl_autoload_functions())) {
@@ -252,6 +254,7 @@ class DebugClassLoader
for (; $i < \count($symbols); ++$i) {
if (!is_subclass_of($symbols[$i], MockObject::class)
&& !is_subclass_of($symbols[$i], Stub::class)
&& !is_subclass_of($symbols[$i], ProphecySubjectInterface::class)
&& !is_subclass_of($symbols[$i], Proxy::class)
&& !is_subclass_of($symbols[$i], ProxyInterface::class)
@@ -259,6 +262,7 @@ class DebugClassLoader
&& !is_subclass_of($symbols[$i], LegacyProxy::class)
&& !is_subclass_of($symbols[$i], MockInterface::class)
&& !is_subclass_of($symbols[$i], IMock::class)
&& !(is_subclass_of($symbols[$i], LazyClosure::class) && str_contains($symbols[$i], "@anonymous\0"))
) {
$loader->checkClass($symbols[$i]);
}
@@ -307,7 +311,7 @@ class DebugClassLoader
$this->checkClass($class, $file);
}
private function checkClass(string $class, string $file = null): void
private function checkClass(string $class, ?string $file = null): void
{
$exists = null === $file || class_exists($class, false) || interface_exists($class, false) || trait_exists($class, false);
@@ -328,7 +332,7 @@ class DebugClassLoader
$name = $refl->getName();
if ($name !== $class && 0 === strcasecmp($name, $class)) {
throw new \RuntimeException(sprintf('Case mismatch between loaded and declared class names: "%s" vs "%s".', $class, $name));
throw new \RuntimeException(\sprintf('Case mismatch between loaded and declared class names: "%s" vs "%s".', $class, $name));
}
$deprecations = $this->checkAnnotations($refl, $name);
@@ -344,14 +348,14 @@ class DebugClassLoader
if (!$exists) {
if (str_contains($class, '/')) {
throw new \RuntimeException(sprintf('Trying to autoload a class with an invalid name "%s". Be careful that the namespace separator is "\" in PHP, not "/".', $class));
throw new \RuntimeException(\sprintf('Trying to autoload a class with an invalid name "%s". Be careful that the namespace separator is "\" in PHP, not "/".', $class));
}
throw new \RuntimeException(sprintf('The autoloader expected class "%s" to be defined in file "%s". The file was found but the class was not in it, the class name or namespace probably has a typo.', $class, $file));
throw new \RuntimeException(\sprintf('The autoloader expected class "%s" to be defined in file "%s". The file was found but the class was not in it, the class name or namespace probably has a typo.', $class, $file));
}
if (self::$caseCheck && $message = $this->checkCase($refl, $file, $class)) {
throw new \RuntimeException(sprintf('Case mismatch between class and real file names: "%s" vs "%s" in "%s".', $message[0], $message[1], $message[2]));
throw new \RuntimeException(\sprintf('Case mismatch between class and real file names: "%s" vs "%s" in "%s".', $message[0], $message[1], $message[2]));
}
}
@@ -412,7 +416,7 @@ class DebugClassLoader
}
if (isset(self::$final[$parent])) {
$deprecations[] = sprintf('The "%s" class is considered final%s It may change without further notice as of its next major version. You should not extend it from "%s".', $parent, self::$final[$parent], $className);
$deprecations[] = \sprintf('The "%s" class is considered final%s It may change without further notice as of its next major version. You should not extend it from "%s".', $parent, self::$final[$parent], $className);
}
}
@@ -425,10 +429,10 @@ class DebugClassLoader
$type = class_exists($class, false) ? 'class' : (interface_exists($class, false) ? 'interface' : 'trait');
$verb = class_exists($use, false) || interface_exists($class, false) ? 'extends' : (interface_exists($use, false) ? 'implements' : 'uses');
$deprecations[] = sprintf('The "%s" %s %s "%s" that is deprecated%s', $className, $type, $verb, $use, self::$deprecated[$use]);
$deprecations[] = \sprintf('The "%s" %s %s "%s" that is deprecated%s', $className, $type, $verb, $use, self::$deprecated[$use]);
}
if (isset(self::$internal[$use]) && strncmp($vendor, str_replace('_', '\\', $use), $vendorLen)) {
$deprecations[] = 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], $className);
$deprecations[] = \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], $className);
}
if (isset(self::$method[$use])) {
if ($refl->isAbstract()) {
@@ -454,7 +458,7 @@ class DebugClassLoader
}
$realName = substr($name, 0, strpos($name, '('));
if (!$refl->hasMethod($realName) || !($methodRefl = $refl->getMethod($realName))->isPublic() || ($static && !$methodRefl->isStatic()) || (!$static && $methodRefl->isStatic())) {
$deprecations[] = sprintf('Class "%s" should implement method "%s::%s%s"%s', $className, ($static ? 'static ' : '').$interface, $name, $returnType ? ': '.$returnType : '', null === $description ? '.' : ': '.$description);
$deprecations[] = \sprintf('Class "%s" should implement method "%s::%s%s"%s', $className, ($static ? 'static ' : '').$interface, $name, $returnType ? ': '.$returnType : '', null === $description ? '.' : ': '.$description);
}
}
}
@@ -518,13 +522,13 @@ class DebugClassLoader
if ($parent && isset(self::$finalMethods[$parent][$method->name])) {
[$declaringClass, $message] = self::$finalMethods[$parent][$method->name];
$deprecations[] = 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, $className);
$deprecations[] = \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, $className);
}
if (isset(self::$internalMethods[$class][$method->name])) {
[$declaringClass, $message] = self::$internalMethods[$class][$method->name];
if (strncmp($ns, $declaringClass, $len)) {
$deprecations[] = 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, $className);
$deprecations[] = \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, $className);
}
}
@@ -543,7 +547,7 @@ class DebugClassLoader
foreach (self::$annotatedParameters[$class][$method->name] as $parameterName => $deprecation) {
if (!isset($definedParameters[$parameterName]) && !isset($doc['param'][$parameterName])) {
$deprecations[] = sprintf($deprecation, $className);
$deprecations[] = \sprintf($deprecation, $className);
}
}
}
@@ -581,7 +585,7 @@ class DebugClassLoader
if ('docblock' === $this->patchTypes['force']) {
$this->patchMethod($method, $returnType, $declaringFile, $normalizedType);
} elseif ('' !== $declaringClass && $this->patchTypes['deprecations']) {
$deprecations[] = sprintf('Method "%s::%s()" might add "%s" as a native return type declaration in the future. Do the same in %s "%s" now to avoid errors or add an explicit @return annotation to suppress this message.', $declaringClass, $method->name, $normalizedType, interface_exists($declaringClass) ? 'implementation' : 'child class', $className);
$deprecations[] = \sprintf('Method "%s::%s()" might add "%s" as a native return type declaration in the future. Do the same in %s "%s" now to avoid errors or add an explicit @return annotation to suppress this message.', $declaringClass, $method->name, $normalizedType, interface_exists($declaringClass) ? 'implementation' : 'child class', $className);
}
}
}
@@ -630,7 +634,7 @@ class DebugClassLoader
}
foreach ($doc['param'] as $parameterName => $parameterType) {
if (!isset($definedParameters[$parameterName])) {
self::$annotatedParameters[$class][$method->name][$parameterName] = sprintf('The "%%s::%s()" method will require a new "%s$%s" argument in the next major version of its %s "%s", not defining it is deprecated.', $method->name, $parameterType ? $parameterType.' ' : '', $parameterName, interface_exists($className) ? 'interface' : 'parent class', $className);
self::$annotatedParameters[$class][$method->name][$parameterName] = \sprintf('The "%%s::%s()" method will require a new "%s$%s" argument in the next major version of its %s "%s", not defining it is deprecated.', $method->name, $parameterType ? $parameterType.' ' : '', $parameterName, interface_exists($className) ? 'interface' : 'parent class', $className);
}
}
}
@@ -650,7 +654,7 @@ class DebugClassLoader
foreach ($parentAndOwnInterfaces as $use) {
if (isset(self::${$type}[$use][$r->name]) && !isset($doc['deprecated']) && ('finalConstants' === $type || substr($use, 0, strrpos($use, '\\')) !== substr($use, 0, strrpos($class, '\\')))) {
$msg = 'finalConstants' === $type ? '%s" constant' : '$%s" property';
$deprecations[] = sprintf('The "%s::'.$msg.' is considered final. You should not override it in "%s".', self::${$type}[$use][$r->name], $r->name, $class);
$deprecations[] = \sprintf('The "%s::'.$msg.' is considered final. You should not override it in "%s".', self::${$type}[$use][$r->name], $r->name, $class);
}
}
@@ -794,7 +798,7 @@ class DebugClassLoader
return $ownInterfaces;
}
private function setReturnType(string $types, string $class, string $method, string $filename, ?string $parent, \ReflectionType $returnType = null): void
private function setReturnType(string $types, string $class, string $method, string $filename, ?string $parent, ?\ReflectionType $returnType = null): void
{
if ('__construct' === $method) {
return;
@@ -891,8 +895,8 @@ class DebugClassLoader
}
}
$phpType = sprintf($nullable ? (1 < \count($phpTypes) ? '%s|null' : '?%s') : '%s', implode($glue, $phpTypes));
$docType = sprintf($nullable ? '%s|null' : '%s', implode($glue, $docTypes));
$phpType = \sprintf($nullable ? (1 < \count($phpTypes) ? '%s|null' : '?%s') : '%s', implode($glue, $phpTypes));
$docType = \sprintf($nullable ? '%s|null' : '%s', implode($glue, $docTypes));
self::$returnTypes[$class][$method] = [$phpType, $docType, $class, $filename];
}
@@ -1024,7 +1028,7 @@ class DebugClassLoader
++$fileOffset;
}
$returnType[$i] = null !== $format ? sprintf($format, $alias) : $alias;
$returnType[$i] = null !== $format ? \sprintf($format, $alias) : $alias;
}
if ('docblock' === $this->patchTypes['force'] || ('object' === $normalizedType && '7.1' === $this->patchTypes['php'])) {
@@ -1212,7 +1216,7 @@ EOTXT;
$static = 'static' === $parts[0];
for ($i = $static ? 2 : 0; null !== $p = $parts[$i] ?? null; $i += 2) {
if (\in_array($p, ['', '|', '&', 'callable'], true) || \in_array(substr($returnType, -1), ['|', '&'], true)) {
if (\in_array($p, ['', 'callable'], true) || \in_array(substr($returnType, -1), ['|', '&'], true) || \in_array($p[0], ['|', '&'], true)) {
$returnType .= trim($parts[$i - 1] ?? '').$p;
continue;
}