Merge branch '5.2' into 5.x

* 5.2:
  Move github templates at the org level
  [Cache] Fix Redis TLS scheme `rediss` for Redis connection
  In calls to mb_ functions, silently transform arg into string
  Switched to non-null defaults in exception constructors
  [Routing] fix conflict with param named class in attribute
  [Cache] fix setting items' metadata on commit()
This commit is contained in:
Nicolas Grekas 2021-02-23 11:10:15 +01:00
commit bc9e946a56
76 changed files with 381 additions and 218 deletions

View File

@ -1,8 +0,0 @@
# Code of Conduct
This project follows a [Code of Conduct][code_of_conduct] in order to ensure an open and welcoming environment.
Please read the full text for understanding the accepted and unaccepted behavior.
Please read also the [reporting guidelines][guidelines], in case you encountered or witnessed any misbehavior.
[code_of_conduct]: https://symfony.com/doc/current/contributing/code_of_conduct/index.html
[guidelines]: https://symfony.com/doc/current/contributing/code_of_conduct/reporting_guidelines.html

View File

@ -1,22 +0,0 @@
---
name: 🐛 Bug Report
about: Report errors and problems
labels: Bug
---
**Symfony version(s) affected**: x.y.z
**Description**
<!-- A clear and concise description of the problem. -->
**How to reproduce**
<!-- Code and/or config needed to reproduce the problem. If it's a complex bug,
create a "bug reproducer" as explained in:
https://symfony.com/doc/current/contributing/code/reproducer.html -->
**Possible Solution**
<!--- Optional: only if you have suggestions on a fix/reason for the bug -->
**Additional context**
<!-- Optional: any other context about the problem: log messages, screenshots, etc. -->

View File

@ -1,12 +0,0 @@
---
name: 🚀 Feature Request
about: RFC and ideas for new features and improvements
---
**Description**
<!-- A clear and concise description of the new feature. -->
**Example**
<!-- A simple example of the new feature in action (include PHP code, YAML config, etc.)
If the new feature changes an existing feature, include a simple before/after comparison. -->

View File

@ -1,11 +0,0 @@
---
name: ⛔ Support Question
about: See https://symfony.com/support for questions about using Symfony and its components
---
We use GitHub issues only to discuss about Symfony bugs and new features. For
this kind of questions about using Symfony or third-party bundles, please use
any of the support alternatives shown in https://symfony.com/support
Thanks!

View File

@ -1,10 +0,0 @@
---
name: ⛔ Documentation Issue
about: See https://github.com/symfony/symfony-docs/issues for documentation issues
---
Symfony Documentation has its own dedicated repository. Please open your
documentation-related issue at https://github.com/symfony/symfony-docs/issues
Thanks!

10
.github/SECURITY.md vendored
View File

@ -1,10 +0,0 @@
Security Policy
===============
If you found any issues that might have security implications,
please send a report to security[at]symfony.com
DO NOT PUBLISH SECURITY REPORTS PUBLICLY.
The full [Security Policy][1] is described in the official documentation.
[1]: https://symfony.com/security

View File

@ -61,7 +61,7 @@ class DelegatingLoader extends BaseDelegatingLoader
// - this handles the case and prevents the second fatal error
// by triggering an exception beforehand.
throw new LoaderLoadException($resource, null, null, null, $type);
throw new LoaderLoadException($resource, null, 0, null, $type);
}
$this->loading = true;

View File

@ -110,6 +110,7 @@ abstract class AbstractTagAwareAdapter implements TagAwareAdapterInterface, TagA
}
$byLifetime[$ttl][$getId($key)] = $value;
$item->metadata = $item->newMetadata;
}
return $byLifetime;

View File

@ -83,6 +83,7 @@ class TagAwareAdapter implements TagAwareAdapterInterface, TagAwareCacheInterfac
$tagsByKey = [];
foreach ($deferred as $key => $item) {
$tagsByKey[$key] = $item->newMetadata[CacheItem::METADATA_TAGS] ?? [];
$item->metadata = $item->newMetadata;
}
return $tagsByKey;

View File

@ -13,7 +13,6 @@ namespace Symfony\Component\Cache\Tests\Adapter;
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\Cache\Adapter\FilesystemTagAwareAdapter;
use Symfony\Component\Cache\Tests\Traits\TagAwareTestTrait;
/**
* @group time-sensitive

View File

@ -13,7 +13,6 @@ namespace Symfony\Component\Cache\Tests\Adapter;
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\Cache\Adapter\PdoAdapter;
use Symfony\Component\Cache\Tests\Traits\PdoPruneableTrait;
/**
* @group time-sensitive

View File

@ -17,7 +17,6 @@ use Doctrine\DBAL\DriverManager;
use Doctrine\DBAL\Schema\Schema;
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\Cache\Adapter\PdoAdapter;
use Symfony\Component\Cache\Tests\Traits\PdoPruneableTrait;
/**
* @group time-sensitive

View File

@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
namespace Symfony\Component\Cache\Tests\Traits;
namespace Symfony\Component\Cache\Tests\Adapter;
trait PdoPruneableTrait
{

View File

@ -13,7 +13,6 @@ namespace Symfony\Component\Cache\Tests\Adapter;
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\Cache\Adapter\RedisTagAwareAdapter;
use Symfony\Component\Cache\Tests\Traits\TagAwareTestTrait;
/**
* @group integration

View File

@ -13,7 +13,6 @@ namespace Symfony\Component\Cache\Tests\Adapter;
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\Cache\Adapter\RedisTagAwareAdapter;
use Symfony\Component\Cache\Tests\Traits\TagAwareTestTrait;
/**
* @group integration

View File

@ -36,36 +36,46 @@ class RedisAdapterTest extends AbstractRedisAdapterTest
return $adapter;
}
/**
* @dataProvider provideValidSchemes
*/
public function testCreateConnection(string $dsnScheme)
public function testCreateConnection()
{
$redis = RedisAdapter::createConnection($dsnScheme.':?host[h1]&host[h2]&host[/foo:]');
$redis = RedisAdapter::createConnection('redis:?host[h1]&host[h2]&host[/foo:]');
$this->assertInstanceOf(\RedisArray::class, $redis);
$this->assertSame(['h1:6379', 'h2:6379', '/foo'], $redis->_hosts());
@$redis = null; // some versions of phpredis connect on destruct, let's silence the warning
$redisHost = getenv('REDIS_HOST');
$redis = RedisAdapter::createConnection($dsnScheme.'://'.$redisHost);
$redis = RedisAdapter::createConnection('redis://'.$redisHost);
$this->assertInstanceOf(\Redis::class, $redis);
$this->assertTrue($redis->isConnected());
$this->assertSame(0, $redis->getDbNum());
$redis = RedisAdapter::createConnection($dsnScheme.'://'.$redisHost.'/2');
$redis = RedisAdapter::createConnection('redis://'.$redisHost.'/2');
$this->assertSame(2, $redis->getDbNum());
$redis = RedisAdapter::createConnection($dsnScheme.'://'.$redisHost, ['timeout' => 3]);
$redis = RedisAdapter::createConnection('redis://'.$redisHost, ['timeout' => 3]);
$this->assertEquals(3, $redis->getTimeout());
$redis = RedisAdapter::createConnection($dsnScheme.'://'.$redisHost.'?timeout=4');
$redis = RedisAdapter::createConnection('redis://'.$redisHost.'?timeout=4');
$this->assertEquals(4, $redis->getTimeout());
$redis = RedisAdapter::createConnection($dsnScheme.'://'.$redisHost, ['read_timeout' => 5]);
$redis = RedisAdapter::createConnection('redis://'.$redisHost, ['read_timeout' => 5]);
$this->assertEquals(5, $redis->getReadTimeout());
}
public function testCreateTlsConnection()
{
$redis = RedisAdapter::createConnection('rediss:?host[h1]&host[h2]&host[/foo:]');
$this->assertInstanceOf(\RedisArray::class, $redis);
$this->assertSame(['tls://h1:6379', 'tls://h2:6379', '/foo'], $redis->_hosts());
@$redis = null; // some versions of phpredis connect on destruct, let's silence the warning
$redisHost = getenv('REDIS_HOST');
$redis = RedisAdapter::createConnection('rediss://'.$redisHost.'?lazy=1');
$this->assertInstanceOf(RedisProxy::class, $redis);
}
/**
* @dataProvider provideFailedCreateConnection
*/
@ -95,14 +105,6 @@ class RedisAdapterTest extends AbstractRedisAdapterTest
RedisAdapter::createConnection($dsn);
}
public function provideValidSchemes(): array
{
return [
['redis'],
['rediss'],
];
}
public function provideInvalidCreateConnection(): array
{
return [

View File

@ -13,7 +13,6 @@ namespace Symfony\Component\Cache\Tests\Adapter;
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\Cache\Adapter\RedisTagAwareAdapter;
use Symfony\Component\Cache\Tests\Traits\TagAwareTestTrait;
use Symfony\Component\Cache\Traits\RedisProxy;
/**

View File

@ -13,7 +13,6 @@ namespace Symfony\Component\Cache\Tests\Adapter;
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\Cache\Adapter\RedisTagAwareAdapter;
use Symfony\Component\Cache\Tests\Traits\TagAwareTestTrait;
/**
* @group integration

View File

@ -13,7 +13,6 @@ namespace Symfony\Component\Cache\Tests\Adapter;
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\Cache\Adapter\RedisTagAwareAdapter;
use Symfony\Component\Cache\Tests\Traits\TagAwareTestTrait;
use Symfony\Component\Cache\Traits\RedisClusterProxy;
/**

View File

@ -19,7 +19,6 @@ use Symfony\Component\Cache\Adapter\ArrayAdapter;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Cache\Adapter\TagAwareAdapter;
use Symfony\Component\Cache\Tests\Fixtures\PrunableAdapter;
use Symfony\Component\Cache\Tests\Traits\TagAwareTestTrait;
use Symfony\Component\Filesystem\Filesystem;
/**

View File

@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
namespace Symfony\Component\Cache\Tests\Traits;
namespace Symfony\Component\Cache\Tests\Adapter;
use Symfony\Component\Cache\CacheItem;
@ -136,7 +136,9 @@ trait TagAwareTestTrait
$pool = $this->createCachePool();
$i = $pool->getItem('k');
$this->assertSame([], $i->getMetadata());
$pool->save($i->tag('foo'));
$this->assertSame(['foo' => 'foo'], $i->getMetadata()[CacheItem::METADATA_TAGS]);
$i = $pool->getItem('k');
$this->assertSame(['foo' => 'foo'], $i->getMetadata()[CacheItem::METADATA_TAGS]);

View File

@ -119,6 +119,9 @@ trait RedisTrait
$query = $hosts = [];
$tls = 'rediss' === $scheme;
$tcpScheme = $tls ? 'tls' : 'tcp';
if (isset($params['query'])) {
parse_str($params['query'], $query);
@ -131,9 +134,9 @@ trait RedisTrait
parse_str($parameters, $parameters);
}
if (false === $i = strrpos($host, ':')) {
$hosts[$host] = ['scheme' => 'tcp', 'host' => $host, 'port' => 6379] + $parameters;
$hosts[$host] = ['scheme' => $tcpScheme, 'host' => $host, 'port' => 6379] + $parameters;
} elseif ($port = (int) substr($host, 1 + $i)) {
$hosts[$host] = ['scheme' => 'tcp', 'host' => substr($host, 0, $i), 'port' => $port] + $parameters;
$hosts[$host] = ['scheme' => $tcpScheme, 'host' => substr($host, 0, $i), 'port' => $port] + $parameters;
} else {
$hosts[$host] = ['scheme' => 'unix', 'path' => substr($host, 0, $i)] + $parameters;
}
@ -149,7 +152,7 @@ trait RedisTrait
}
if (isset($params['host'])) {
array_unshift($hosts, ['scheme' => 'tcp', 'host' => $params['host'], 'port' => $params['port'] ?? 6379]);
array_unshift($hosts, ['scheme' => $tcpScheme, 'host' => $params['host'], 'port' => $params['port'] ?? 6379]);
} else {
array_unshift($hosts, ['scheme' => 'unix', 'path' => $params['path']]);
}
@ -179,10 +182,14 @@ trait RedisTrait
$connect = $params['persistent'] || $params['persistent_id'] ? 'pconnect' : 'connect';
$redis = new $class();
$initializer = static function ($redis) use ($connect, $params, $dsn, $auth, $hosts) {
$initializer = static function ($redis) use ($connect, $params, $dsn, $auth, $hosts, $tls) {
$host = $hosts[0]['host'] ?? $hosts[0]['path'];
$port = $hosts[0]['port'] ?? null;
if (isset($hosts[0]['host']) && $tls) {
$host = 'tls://'.$host;
}
if (isset($params['redis_sentinel'])) {
$sentinel = new \RedisSentinel($host, $port, $params['timeout'], (string) $params['persistent_id'], $params['retry_interval'], $params['read_timeout']);
@ -228,7 +235,11 @@ trait RedisTrait
}
} elseif (is_a($class, \RedisArray::class, true)) {
foreach ($hosts as $i => $host) {
$hosts[$i] = 'tcp' === $host['scheme'] ? $host['host'].':'.$host['port'] : $host['path'];
switch ($host['scheme']) {
case 'tcp': $hosts[$i] = $host['host'].':'.$host['port']; break;
case 'tls': $hosts[$i] = 'tls://'.$host['host'].':'.$host['port']; break;
default: $hosts[$i] = $host['path'];
}
}
$params['lazy_connect'] = $params['lazy'] ?? true;
$params['connect_timeout'] = $params['timeout'];
@ -245,7 +256,11 @@ trait RedisTrait
} elseif (is_a($class, \RedisCluster::class, true)) {
$initializer = static function () use ($class, $params, $dsn, $hosts) {
foreach ($hosts as $i => $host) {
$hosts[$i] = 'tcp' === $host['scheme'] ? $host['host'].':'.$host['port'] : $host['path'];
switch ($host['scheme']) {
case 'tcp': $hosts[$i] = $host['host'].':'.$host['port']; break;
case 'tls': $hosts[$i] = 'tls://'.$host['host'].':'.$host['port']; break;
default: $hosts[$i] = $host['path'];
}
}
try {

View File

@ -18,7 +18,7 @@ namespace Symfony\Component\Config\Exception;
*/
class FileLoaderImportCircularReferenceException extends LoaderLoadException
{
public function __construct(array $resources, int $code = null, \Throwable $previous = null)
public function __construct(array $resources, ?int $code = 0, \Throwable $previous = null)
{
$message = sprintf('Circular reference detected in "%s" ("%s" > "%s").', $this->varToString($resources[0]), implode('" > "', $resources), $resources[0]);

View File

@ -34,7 +34,7 @@ class DelegatingLoader extends Loader
public function load($resource, string $type = null)
{
if (false === $loader = $this->resolver->resolve($resource, $type)) {
throw new LoaderLoadException($resource, null, null, null, $type);
throw new LoaderLoadException($resource, null, 0, null, $type);
}
return $loader->load($resource, $type);

View File

@ -171,7 +171,7 @@ abstract class FileLoader extends Loader
throw $e;
}
throw new LoaderLoadException($resource, $sourceResource, null, $e, $type);
throw new LoaderLoadException($resource, $sourceResource, 0, $e, $type);
}
}

View File

@ -76,7 +76,7 @@ abstract class Loader implements LoaderInterface
$loader = null === $this->resolver ? false : $this->resolver->resolve($resource, $type);
if (false === $loader) {
throw new LoaderLoadException($resource, null, null, null, $type);
throw new LoaderLoadException($resource, null, 0, null, $type);
}
return $loader;

View File

@ -24,13 +24,13 @@ class LoaderLoadExceptionTest extends TestCase
public function testMessageCannotLoadResourceWithType()
{
$exception = new LoaderLoadException('resource', null, null, null, 'foobar');
$exception = new LoaderLoadException('resource', null, 0, null, 'foobar');
$this->assertEquals('Cannot load resource "resource". Make sure there is a loader supporting the "foobar" type.', $exception->getMessage());
}
public function testMessageCannotLoadResourceWithAnnotationType()
{
$exception = new LoaderLoadException('resource', null, null, null, 'annotation');
$exception = new LoaderLoadException('resource', null, 0, null, 'annotation');
$this->assertEquals('Cannot load resource "resource". Make sure annotations are installed and enabled.', $exception->getMessage());
}
@ -56,7 +56,7 @@ class LoaderLoadExceptionTest extends TestCase
$exception = new LoaderLoadException(
'resource',
null,
null,
0,
new \Exception('There was a previous error with an ending dot.')
);
$this->assertEquals(
@ -70,7 +70,7 @@ class LoaderLoadExceptionTest extends TestCase
$exception = new LoaderLoadException(
'resource',
null,
null,
0,
new \Exception('There was a previous error with no ending dot')
);
$this->assertEquals(
@ -84,7 +84,7 @@ class LoaderLoadExceptionTest extends TestCase
$exception = new LoaderLoadException(
'@resource',
null,
null,
0,
new \Exception('There was a previous error with an ending dot.')
);
$this->assertEquals(

View File

@ -21,10 +21,10 @@ class CommandNotFoundException extends \InvalidArgumentException implements Exce
private $alternatives;
/**
* @param string $message Exception message to throw
* @param array $alternatives List of similar defined names
* @param int $code Exception code
* @param \Throwable $previous Previous exception used for the exception chaining
* @param string $message Exception message to throw
* @param string[] $alternatives List of similar defined names
* @param int $code Exception code
* @param \Throwable|null $previous Previous exception used for the exception chaining
*/
public function __construct(string $message, array $alternatives = [], int $code = 0, \Throwable $previous = null)
{
@ -34,7 +34,7 @@ class CommandNotFoundException extends \InvalidArgumentException implements Exce
}
/**
* @return array A list of similar defined names
* @return string[] A list of similar defined names
*/
public function getAlternatives()
{

View File

@ -45,6 +45,8 @@ abstract class Helper implements HelperInterface
*/
public static function strlen(?string $string)
{
$string = (string) $string;
if (false === $encoding = mb_detect_encoding($string, null, true)) {
return \strlen($string);
}
@ -59,6 +61,8 @@ abstract class Helper implements HelperInterface
*/
public static function substr(string $string, int $from, int $length = null)
{
$string = (string) $string;
if (false === $encoding = mb_detect_encoding($string, null, true)) {
return substr($string, $from, $length);
}

View File

@ -18,11 +18,11 @@ namespace Symfony\Component\HttpKernel\Exception;
class AccessDeniedHttpException extends HttpException
{
/**
* @param string $message The internal exception message
* @param \Throwable $previous The previous exception
* @param int $code The internal exception code
* @param string|null $message The internal exception message
* @param \Throwable|null $previous The previous exception
* @param int $code The internal exception code
*/
public function __construct(string $message = null, \Throwable $previous = null, int $code = 0, array $headers = [])
public function __construct(?string $message = '', \Throwable $previous = null, int $code = 0, array $headers = [])
{
parent::__construct(403, $message, $previous, $headers, $code);
}

View File

@ -17,11 +17,11 @@ namespace Symfony\Component\HttpKernel\Exception;
class BadRequestHttpException extends HttpException
{
/**
* @param string $message The internal exception message
* @param \Throwable $previous The previous exception
* @param int $code The internal exception code
* @param string|null $message The internal exception message
* @param \Throwable|null $previous The previous exception
* @param int $code The internal exception code
*/
public function __construct(string $message = null, \Throwable $previous = null, int $code = 0, array $headers = [])
public function __construct(?string $message = '', \Throwable $previous = null, int $code = 0, array $headers = [])
{
parent::__construct(400, $message, $previous, $headers, $code);
}

View File

@ -17,11 +17,11 @@ namespace Symfony\Component\HttpKernel\Exception;
class ConflictHttpException extends HttpException
{
/**
* @param string $message The internal exception message
* @param \Throwable $previous The previous exception
* @param int $code The internal exception code
* @param string|null $message The internal exception message
* @param \Throwable|null $previous The previous exception
* @param int $code The internal exception code
*/
public function __construct(string $message = null, \Throwable $previous = null, int $code = 0, array $headers = [])
public function __construct(?string $message = '', \Throwable $previous = null, int $code = 0, array $headers = [])
{
parent::__construct(409, $message, $previous, $headers, $code);
}

View File

@ -17,11 +17,11 @@ namespace Symfony\Component\HttpKernel\Exception;
class GoneHttpException extends HttpException
{
/**
* @param string $message The internal exception message
* @param \Throwable $previous The previous exception
* @param int $code The internal exception code
* @param string|null $message The internal exception message
* @param \Throwable|null $previous The previous exception
* @param int $code The internal exception code
*/
public function __construct(string $message = null, \Throwable $previous = null, int $code = 0, array $headers = [])
public function __construct(?string $message = '', \Throwable $previous = null, int $code = 0, array $headers = [])
{
parent::__construct(410, $message, $previous, $headers, $code);
}

View File

@ -21,7 +21,7 @@ class HttpException extends \RuntimeException implements HttpExceptionInterface
private $statusCode;
private $headers;
public function __construct(int $statusCode, string $message = null, \Throwable $previous = null, array $headers = [], ?int $code = 0)
public function __construct(int $statusCode, ?string $message = '', \Throwable $previous = null, array $headers = [], ?int $code = 0)
{
$this->statusCode = $statusCode;
$this->headers = $headers;

View File

@ -17,11 +17,11 @@ namespace Symfony\Component\HttpKernel\Exception;
class LengthRequiredHttpException extends HttpException
{
/**
* @param string $message The internal exception message
* @param \Throwable $previous The previous exception
* @param int $code The internal exception code
* @param string|null $message The internal exception message
* @param \Throwable|null $previous The previous exception
* @param int $code The internal exception code
*/
public function __construct(string $message = null, \Throwable $previous = null, int $code = 0, array $headers = [])
public function __construct(?string $message = '', \Throwable $previous = null, int $code = 0, array $headers = [])
{
parent::__construct(411, $message, $previous, $headers, $code);
}

View File

@ -17,12 +17,12 @@ namespace Symfony\Component\HttpKernel\Exception;
class MethodNotAllowedHttpException extends HttpException
{
/**
* @param array $allow An array of allowed methods
* @param string $message The internal exception message
* @param \Throwable $previous The previous exception
* @param int $code The internal exception code
* @param string[] $allow An array of allowed methods
* @param string|null $message The internal exception message
* @param \Throwable|null $previous The previous exception
* @param int|null $code The internal exception code
*/
public function __construct(array $allow, string $message = null, \Throwable $previous = null, ?int $code = 0, array $headers = [])
public function __construct(array $allow, ?string $message = '', \Throwable $previous = null, ?int $code = 0, array $headers = [])
{
$headers['Allow'] = strtoupper(implode(', ', $allow));

View File

@ -17,11 +17,11 @@ namespace Symfony\Component\HttpKernel\Exception;
class NotAcceptableHttpException extends HttpException
{
/**
* @param string $message The internal exception message
* @param \Throwable $previous The previous exception
* @param int $code The internal exception code
* @param string|null $message The internal exception message
* @param \Throwable|null $previous The previous exception
* @param int $code The internal exception code
*/
public function __construct(string $message = null, \Throwable $previous = null, int $code = 0, array $headers = [])
public function __construct(?string $message = '', \Throwable $previous = null, int $code = 0, array $headers = [])
{
parent::__construct(406, $message, $previous, $headers, $code);
}

View File

@ -17,11 +17,11 @@ namespace Symfony\Component\HttpKernel\Exception;
class NotFoundHttpException extends HttpException
{
/**
* @param string $message The internal exception message
* @param \Throwable $previous The previous exception
* @param int $code The internal exception code
* @param string|null $message The internal exception message
* @param \Throwable|null $previous The previous exception
* @param int $code The internal exception code
*/
public function __construct(string $message = null, \Throwable $previous = null, int $code = 0, array $headers = [])
public function __construct(?string $message = '', \Throwable $previous = null, int $code = 0, array $headers = [])
{
parent::__construct(404, $message, $previous, $headers, $code);
}

View File

@ -17,11 +17,11 @@ namespace Symfony\Component\HttpKernel\Exception;
class PreconditionFailedHttpException extends HttpException
{
/**
* @param string $message The internal exception message
* @param \Throwable $previous The previous exception
* @param int $code The internal exception code
* @param string|null $message The internal exception message
* @param \Throwable|null $previous The previous exception
* @param int $code The internal exception code
*/
public function __construct(string $message = null, \Throwable $previous = null, int $code = 0, array $headers = [])
public function __construct(?string $message = '', \Throwable $previous = null, int $code = 0, array $headers = [])
{
parent::__construct(412, $message, $previous, $headers, $code);
}

View File

@ -19,11 +19,11 @@ namespace Symfony\Component\HttpKernel\Exception;
class PreconditionRequiredHttpException extends HttpException
{
/**
* @param string $message The internal exception message
* @param \Throwable $previous The previous exception
* @param int $code The internal exception code
* @param string|null $message The internal exception message
* @param \Throwable|null $previous The previous exception
* @param int $code The internal exception code
*/
public function __construct(string $message = null, \Throwable $previous = null, int $code = 0, array $headers = [])
public function __construct(?string $message = '', \Throwable $previous = null, int $code = 0, array $headers = [])
{
parent::__construct(428, $message, $previous, $headers, $code);
}

View File

@ -17,12 +17,12 @@ namespace Symfony\Component\HttpKernel\Exception;
class ServiceUnavailableHttpException extends HttpException
{
/**
* @param int|string $retryAfter The number of seconds or HTTP-date after which the request may be retried
* @param string $message The internal exception message
* @param \Throwable $previous The previous exception
* @param int $code The internal exception code
* @param int|string|null $retryAfter The number of seconds or HTTP-date after which the request may be retried
* @param string|null $message The internal exception message
* @param \Throwable|null $previous The previous exception
* @param int|null $code The internal exception code
*/
public function __construct($retryAfter = null, string $message = null, \Throwable $previous = null, ?int $code = 0, array $headers = [])
public function __construct($retryAfter = null, ?string $message = '', \Throwable $previous = null, ?int $code = 0, array $headers = [])
{
if ($retryAfter) {
$headers['Retry-After'] = $retryAfter;

View File

@ -19,12 +19,12 @@ namespace Symfony\Component\HttpKernel\Exception;
class TooManyRequestsHttpException extends HttpException
{
/**
* @param int|string $retryAfter The number of seconds or HTTP-date after which the request may be retried
* @param string $message The internal exception message
* @param \Throwable $previous The previous exception
* @param int $code The internal exception code
* @param int|string|null $retryAfter The number of seconds or HTTP-date after which the request may be retried
* @param string|null $message The internal exception message
* @param \Throwable|null $previous The previous exception
* @param int|null $code The internal exception code
*/
public function __construct($retryAfter = null, string $message = null, \Throwable $previous = null, ?int $code = 0, array $headers = [])
public function __construct($retryAfter = null, ?string $message = '', \Throwable $previous = null, ?int $code = 0, array $headers = [])
{
if ($retryAfter) {
$headers['Retry-After'] = $retryAfter;

View File

@ -17,12 +17,12 @@ namespace Symfony\Component\HttpKernel\Exception;
class UnauthorizedHttpException extends HttpException
{
/**
* @param string $challenge WWW-Authenticate challenge string
* @param string $message The internal exception message
* @param \Throwable $previous The previous exception
* @param int $code The internal exception code
* @param string $challenge WWW-Authenticate challenge string
* @param string|null $message The internal exception message
* @param \Throwable|null $previous The previous exception
* @param int|null $code The internal exception code
*/
public function __construct(string $challenge, string $message = null, \Throwable $previous = null, ?int $code = 0, array $headers = [])
public function __construct(string $challenge, ?string $message = '', \Throwable $previous = null, ?int $code = 0, array $headers = [])
{
$headers['WWW-Authenticate'] = $challenge;

View File

@ -17,11 +17,11 @@ namespace Symfony\Component\HttpKernel\Exception;
class UnprocessableEntityHttpException extends HttpException
{
/**
* @param string $message The internal exception message
* @param \Throwable $previous The previous exception
* @param int $code The internal exception code
* @param string|null $message The internal exception message
* @param \Throwable|null $previous The previous exception
* @param int $code The internal exception code
*/
public function __construct(string $message = null, \Throwable $previous = null, int $code = 0, array $headers = [])
public function __construct(?string $message = '', \Throwable $previous = null, int $code = 0, array $headers = [])
{
parent::__construct(422, $message, $previous, $headers, $code);
}

View File

@ -17,11 +17,11 @@ namespace Symfony\Component\HttpKernel\Exception;
class UnsupportedMediaTypeHttpException extends HttpException
{
/**
* @param string $message The internal exception message
* @param \Throwable $previous The previous exception
* @param int $code The internal exception code
* @param string|null $message The internal exception message
* @param \Throwable|null $previous The previous exception
* @param int $code The internal exception code
*/
public function __construct(string $message = null, \Throwable $previous = null, int $code = 0, array $headers = [])
public function __construct(?string $message = '', \Throwable $previous = null, int $code = 0, array $headers = [])
{
parent::__construct(415, $message, $previous, $headers, $code);
}

View File

@ -3,10 +3,11 @@
namespace Symfony\Component\HttpKernel\Tests\Exception;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\HttpException;
class AccessDeniedHttpExceptionTest extends HttpExceptionTest
{
protected function createException(string $message = null, \Throwable $previous = null, ?int $code = 0, array $headers = [])
protected function createException(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []): HttpException
{
return new AccessDeniedHttpException($message, $previous, $code, $headers);
}

View File

@ -3,10 +3,11 @@
namespace Symfony\Component\HttpKernel\Tests\Exception;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\HttpException;
class BadRequestHttpExceptionTest extends HttpExceptionTest
{
protected function createException(string $message = null, \Throwable $previous = null, ?int $code = 0, array $headers = [])
protected function createException(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []): HttpException
{
return new BadRequestHttpException($message, $previous, $code, $headers);
}

View File

@ -3,10 +3,11 @@
namespace Symfony\Component\HttpKernel\Tests\Exception;
use Symfony\Component\HttpKernel\Exception\ConflictHttpException;
use Symfony\Component\HttpKernel\Exception\HttpException;
class ConflictHttpExceptionTest extends HttpExceptionTest
{
protected function createException(string $message = null, \Throwable $previous = null, ?int $code = 0, array $headers = [])
protected function createException(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []): HttpException
{
return new ConflictHttpException($message, $previous, $code, $headers);
}

View File

@ -3,10 +3,11 @@
namespace Symfony\Component\HttpKernel\Tests\Exception;
use Symfony\Component\HttpKernel\Exception\GoneHttpException;
use Symfony\Component\HttpKernel\Exception\HttpException;
class GoneHttpExceptionTest extends HttpExceptionTest
{
protected function createException(string $message = null, \Throwable $previous = null, ?int $code = 0, array $headers = [])
protected function createException(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []): HttpException
{
return new GoneHttpException($message, $previous, $code, $headers);
}

View File

@ -32,7 +32,7 @@ class HttpExceptionTest extends TestCase
*/
public function testHeadersConstructor($headers)
{
$exception = new HttpException(200, null, null, $headers);
$exception = new HttpException(200, '', null, $headers);
$this->assertSame($headers, $exception->getHeaders());
}
@ -50,11 +50,11 @@ class HttpExceptionTest extends TestCase
{
$previous = new class('Error of PHP 7+') extends \Error {
};
$exception = $this->createException(null, $previous);
$exception = $this->createException('', $previous);
$this->assertSame($previous, $exception->getPrevious());
}
protected function createException(string $message = null, \Throwable $previous = null, ?int $code = 0, array $headers = [])
protected function createException(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []): HttpException
{
return new HttpException(200, $message, $previous, $headers, $code);
}

View File

@ -2,11 +2,12 @@
namespace Symfony\Component\HttpKernel\Tests\Exception;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\Exception\LengthRequiredHttpException;
class LengthRequiredHttpExceptionTest extends HttpExceptionTest
{
protected function createException(string $message = null, \Throwable $previous = null, ?int $code = 0, array $headers = [])
protected function createException(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []): HttpException
{
return new LengthRequiredHttpException($message, $previous, $code, $headers);
}

View File

@ -2,6 +2,7 @@
namespace Symfony\Component\HttpKernel\Tests\Exception;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
class MethodNotAllowedHttpExceptionTest extends HttpExceptionTest
@ -18,7 +19,7 @@ class MethodNotAllowedHttpExceptionTest extends HttpExceptionTest
'Cache-Control' => 'public, s-maxage=1200',
];
$exception = new MethodNotAllowedHttpException(['get'], null, null, null, $headers);
$exception = new MethodNotAllowedHttpException(['get'], '', null, 0, $headers);
$headers['Allow'] = 'GET';
@ -35,7 +36,7 @@ class MethodNotAllowedHttpExceptionTest extends HttpExceptionTest
$this->assertSame($headers, $exception->getHeaders());
}
protected function createException(string $message = null, \Throwable $previous = null, ?int $code = 0, array $headers = [])
protected function createException(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []): HttpException
{
return new MethodNotAllowedHttpException(['get'], $message, $previous, $code, $headers);
}

View File

@ -2,11 +2,12 @@
namespace Symfony\Component\HttpKernel\Tests\Exception;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\Exception\NotAcceptableHttpException;
class NotAcceptableHttpExceptionTest extends HttpExceptionTest
{
protected function createException(string $message = null, \Throwable $previous = null, ?int $code = 0, array $headers = [])
protected function createException(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []): HttpException
{
return new NotAcceptableHttpException($message, $previous, $code, $headers);
}

View File

@ -2,11 +2,12 @@
namespace Symfony\Component\HttpKernel\Tests\Exception;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class NotFoundHttpExceptionTest extends HttpExceptionTest
{
protected function createException(string $message = null, \Throwable $previous = null, ?int $code = 0, array $headers = [])
protected function createException(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []): HttpException
{
return new NotFoundHttpException($message, $previous, $code, $headers);
}

View File

@ -2,11 +2,12 @@
namespace Symfony\Component\HttpKernel\Tests\Exception;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\Exception\PreconditionFailedHttpException;
class PreconditionFailedHttpExceptionTest extends HttpExceptionTest
{
protected function createException(string $message = null, \Throwable $previous = null, ?int $code = 0, array $headers = [])
protected function createException(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []): HttpException
{
return new PreconditionFailedHttpException($message, $previous, $code, $headers);
}

View File

@ -2,11 +2,12 @@
namespace Symfony\Component\HttpKernel\Tests\Exception;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\Exception\PreconditionRequiredHttpException;
class PreconditionRequiredHttpExceptionTest extends HttpExceptionTest
{
protected function createException(string $message = null, \Throwable $previous = null, ?int $code = 0, array $headers = [])
protected function createException(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []): HttpException
{
return new PreconditionRequiredHttpException($message, $previous, $code, $headers);
}

View File

@ -2,6 +2,7 @@
namespace Symfony\Component\HttpKernel\Tests\Exception;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException;
class ServiceUnavailableHttpExceptionTest extends HttpExceptionTest
@ -18,7 +19,7 @@ class ServiceUnavailableHttpExceptionTest extends HttpExceptionTest
'Cache-Control' => 'public, s-maxage=1337',
];
$exception = new ServiceUnavailableHttpException(1337, null, null, null, $headers);
$exception = new ServiceUnavailableHttpException(1337, '', null, 0, $headers);
$headers['Retry-After'] = 1337;
@ -35,7 +36,7 @@ class ServiceUnavailableHttpExceptionTest extends HttpExceptionTest
$this->assertSame($headers, $exception->getHeaders());
}
protected function createException(string $message = null, \Throwable $previous = null, ?int $code = 0, array $headers = [])
protected function createException(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []): HttpException
{
return new ServiceUnavailableHttpException(null, $message, $previous, $code, $headers);
}

View File

@ -2,6 +2,7 @@
namespace Symfony\Component\HttpKernel\Tests\Exception;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException;
class TooManyRequestsHttpExceptionTest extends HttpExceptionTest
@ -18,7 +19,7 @@ class TooManyRequestsHttpExceptionTest extends HttpExceptionTest
'Cache-Control' => 'public, s-maxage=69',
];
$exception = new TooManyRequestsHttpException(69, null, null, null, $headers);
$exception = new TooManyRequestsHttpException(69, '', null, 0, $headers);
$headers['Retry-After'] = 69;
@ -35,7 +36,7 @@ class TooManyRequestsHttpExceptionTest extends HttpExceptionTest
$this->assertSame($headers, $exception->getHeaders());
}
protected function createException(string $message = null, \Throwable $previous = null, ?int $code = 0, array $headers = [])
protected function createException(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []): HttpException
{
return new TooManyRequestsHttpException(null, $message, $previous, $code, $headers);
}

View File

@ -2,6 +2,7 @@
namespace Symfony\Component\HttpKernel\Tests\Exception;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
class UnauthorizedHttpExceptionTest extends HttpExceptionTest
@ -18,7 +19,7 @@ class UnauthorizedHttpExceptionTest extends HttpExceptionTest
'Cache-Control' => 'public, s-maxage=1200',
];
$exception = new UnauthorizedHttpException('Challenge', null, null, null, $headers);
$exception = new UnauthorizedHttpException('Challenge', '', null, 0, $headers);
$headers['WWW-Authenticate'] = 'Challenge';
@ -35,7 +36,7 @@ class UnauthorizedHttpExceptionTest extends HttpExceptionTest
$this->assertSame($headers, $exception->getHeaders());
}
protected function createException(string $message = null, \Throwable $previous = null, ?int $code = 0, array $headers = [])
protected function createException(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []): HttpException
{
return new UnauthorizedHttpException('Challenge', $message, $previous, $code, $headers);
}

View File

@ -2,11 +2,12 @@
namespace Symfony\Component\HttpKernel\Tests\Exception;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException;
class UnprocessableEntityHttpExceptionTest extends HttpExceptionTest
{
protected function createException(string $message = null, \Throwable $previous = null, ?int $code = 0, array $headers = [])
protected function createException(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []): HttpException
{
return new UnprocessableEntityHttpException($message, $previous, $code, $headers);
}

View File

@ -2,11 +2,12 @@
namespace Symfony\Component\HttpKernel\Tests\Exception;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\Exception\UnsupportedMediaTypeHttpException;
class UnsupportedMediaTypeHttpExceptionTest extends HttpExceptionTest
{
protected function createException(string $message = null, \Throwable $previous = null, ?int $code = 0, array $headers = [])
protected function createException(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []): HttpException
{
return new UnsupportedMediaTypeHttpException($message, $previous, $code, $headers);
}

View File

@ -20,7 +20,7 @@ class HttpTransportException extends TransportException
{
private $response;
public function __construct(string $message = null, ResponseInterface $response, int $code = 0, \Throwable $previous = null)
public function __construct(?string $message, ResponseInterface $response, int $code = 0, \Throwable $previous = null)
{
parent::__construct($message, $code, $previous);

View File

@ -22,7 +22,10 @@ class MethodNotAllowedException extends \RuntimeException implements ExceptionIn
{
protected $allowedMethods = [];
public function __construct(array $allowedMethods, string $message = null, int $code = 0, \Throwable $previous = null)
/**
* @param string[] $allowedMethods
*/
public function __construct(array $allowedMethods, ?string $message = '', int $code = 0, \Throwable $previous = null)
{
$this->allowedMethods = array_map('strtoupper', $allowedMethods);
@ -32,7 +35,7 @@ class MethodNotAllowedException extends \RuntimeException implements ExceptionIn
/**
* Gets the allowed HTTP methods.
*
* @return array
* @return string[]
*/
public function getAllowedMethods()
{

View File

@ -97,10 +97,8 @@ class AnnotationFileLoader extends FileLoader
if (\defined('T_NAME_QUALIFIED')) {
$nsTokens[\T_NAME_QUALIFIED] = true;
}
for ($i = 0; isset($tokens[$i]); ++$i) {
$token = $tokens[$i];
if (!isset($token[1])) {
continue;
}
@ -122,6 +120,9 @@ class AnnotationFileLoader extends FileLoader
$skipClassToken = false;
for ($j = $i - 1; $j > 0; --$j) {
if (!isset($tokens[$j][1])) {
if ('(' === $tokens[$j] || ',' === $tokens[$j]) {
$skipClassToken = true;
}
break;
}

View File

@ -350,11 +350,11 @@ class RouteCollectionBuilder
}
if (null === $resolver = $this->loader->getResolver()) {
throw new LoaderLoadException($resource, null, null, null, $type);
throw new LoaderLoadException($resource, null, 0, null, $type);
}
if (false === $loader = $resolver->resolve($resource, $type)) {
throw new LoaderLoadException($resource, null, null, null, $type);
throw new LoaderLoadException($resource, null, 0, null, $type);
}
$collections = $loader->load($resource, $type);

View File

@ -0,0 +1,16 @@
<?php
namespace Symfony\Component\Routing\Tests\Fixtures\Attributes;
#[\Attribute(\Attribute::TARGET_CLASS)]
class FooAttributes
{
public string $class;
public array $foo = [];
public function __construct(string $class, array $foo)
{
$this->class = $class;
$this->foo = $foo;
}
}

View File

@ -0,0 +1,18 @@
<?php
namespace Symfony\Component\Routing\Tests\Fixtures\AttributesFixtures;
use Symfony\Component\Routing\Tests\Fixtures\Attributes\FooAttributes;
use Symfony\Component\Security\Core\User\User;
#[FooAttributes(
foo: [
'bar' => ['foo','bar'],
'foo'
],
class: User::class
)]
class AttributesClassParamAfterCommaController
{
}

View File

@ -0,0 +1,18 @@
<?php
namespace Symfony\Component\Routing\Tests\Fixtures\AttributesFixtures;
use Symfony\Component\Routing\Tests\Fixtures\Attributes\FooAttributes;
use Symfony\Component\Security\Core\User\User;
#[FooAttributes(
class: User::class,
foo: [
'bar' => ['foo','bar'],
'foo'
]
)]
class AttributesClassParamAfterParenthesisController
{
}

View File

@ -0,0 +1,12 @@
<?php
namespace Symfony\Component\Routing\Tests\Fixtures\AttributesFixtures;
use Symfony\Component\Routing\Tests\Fixtures\Attributes\FooAttributes;
use Symfony\Component\Security\Core\User\User;
#[FooAttributes(foo: ['bar' => ['foo','bar'],'foo'],class: User::class)]
class AttributesClassParamInlineAfterCommaController
{
}

View File

@ -0,0 +1,12 @@
<?php
namespace Symfony\Component\Routing\Tests\Fixtures\AttributesFixtures;
use Symfony\Component\Routing\Tests\Fixtures\Attributes\FooAttributes;
use Symfony\Component\Security\Core\User\User;
#[FooAttributes(class: User::class,foo: ['bar' => ['foo','bar'],'foo'])]
class AttributesClassParamInlineAfterParenthesisController
{
}

View File

@ -0,0 +1,12 @@
<?php
namespace Symfony\Component\Routing\Tests\Fixtures\AttributesFixtures;
use Symfony\Component\Routing\Tests\Fixtures\Attributes\FooAttributes;
use Symfony\Component\Security\Core\User\User;
#[FooAttributes(foo: ['bar' => ['foo','bar'],'foo'],class: 'Symfony\Component\Security\Core\User\User')]
class AttributesClassParamInlineQuotedAfterCommaController
{
}

View File

@ -0,0 +1,12 @@
<?php
namespace Symfony\Component\Routing\Tests\Fixtures\AttributesFixtures;
use Symfony\Component\Routing\Tests\Fixtures\Attributes\FooAttributes;
use Symfony\Component\Security\Core\User\User;
#[FooAttributes(class: 'Symfony\Component\Security\Core\User\User',foo: ['bar' => ['foo','bar'],'foo'])]
class AttributesClassParamInlineQuotedAfterParenthesisController
{
}

View File

@ -0,0 +1,17 @@
<?php
namespace Symfony\Component\Routing\Tests\Fixtures\AttributesFixtures;
use Symfony\Component\Routing\Tests\Fixtures\Attributes\FooAttributes;
#[FooAttributes(
foo: [
'bar' => ['foo','bar'],
'foo'
],
class: 'Symfony\Component\Security\Core\User\User'
)]
class AttributesClassParamQuotedAfterCommaController
{
}

View File

@ -0,0 +1,17 @@
<?php
namespace Symfony\Component\Routing\Tests\Fixtures\AttributesFixtures;
use Symfony\Component\Routing\Tests\Fixtures\Attributes\FooAttributes;
#[FooAttributes(
class: 'Symfony\Component\Security\Core\User\User',
foo: [
'bar' => ['foo','bar'],
'foo'
]
)]
class AttributesClassParamQuotedAfterParenthesisController
{
}

View File

@ -85,4 +85,72 @@ class AnnotationFileLoaderTest extends AbstractAnnotationLoaderTest
$this->assertTrue($this->loader->supports($fixture, 'annotation'), '->supports() checks the resource type if specified');
$this->assertFalse($this->loader->supports($fixture, 'foo'), '->supports() checks the resource type if specified');
}
/**
* @requires PHP 8
*/
public function testLoadAttributesClassAfterComma()
{
$this->reader->expects($this->once())->method('getClassAnnotation');
$this->loader->load(__DIR__.'/../Fixtures/AttributesFixtures/AttributesClassParamAfterCommaController.php');
}
public function testLoadAttributesInlineClassAfterComma()
{
$this->reader->expects($this->once())->method('getClassAnnotation');
$this->loader->load(__DIR__.'/../Fixtures/AttributesFixtures/AttributesClassParamInlineAfterCommaController.php');
}
/**
* @requires PHP 8
*/
public function testLoadAttributesQuotedClassAfterComma()
{
$this->reader->expects($this->once())->method('getClassAnnotation');
$this->loader->load(__DIR__.'/../Fixtures/AttributesFixtures/AttributesClassParamQuotedAfterCommaController.php');
}
public function testLoadAttributesInlineQuotedClassAfterComma()
{
$this->reader->expects($this->once())->method('getClassAnnotation');
$this->loader->load(__DIR__.'/../Fixtures/AttributesFixtures/AttributesClassParamInlineQuotedAfterCommaController.php');
}
/**
* @requires PHP 8
*/
public function testLoadAttributesClassAfterParenthesis()
{
$this->reader->expects($this->once())->method('getClassAnnotation');
$this->loader->load(__DIR__.'/../Fixtures/AttributesFixtures/AttributesClassParamAfterParenthesisController.php');
}
public function testLoadAttributesInlineClassAfterParenthesis()
{
$this->reader->expects($this->once())->method('getClassAnnotation');
$this->loader->load(__DIR__.'/../Fixtures/AttributesFixtures/AttributesClassParamInlineAfterParenthesisController.php');
}
/**
* @requires PHP 8
*/
public function testLoadAttributesQuotedClassAfterParenthesis()
{
$this->reader->expects($this->once())->method('getClassAnnotation');
$this->loader->load(__DIR__.'/../Fixtures/AttributesFixtures/AttributesClassParamQuotedAfterParenthesisController.php');
}
public function testLoadAttributesInlineQuotedClassAfterParenthesis()
{
$this->reader->expects($this->once())->method('getClassAnnotation');
$this->loader->load(__DIR__.'/../Fixtures/AttributesFixtures/AttributesClassParamInlineQuotedAfterParenthesisController.php');
}
}

View File

@ -28,7 +28,6 @@ class ParseException extends RuntimeException
* @param int $parsedLine The line where the error occurred
* @param string|null $snippet The snippet of code near the problem
* @param string|null $parsedFile The file name where the error occurred
* @param \Exception|null $previous The previous exception
*/
public function __construct(string $message, int $parsedLine = -1, string $snippet = null, string $parsedFile = null, \Throwable $previous = null)
{