 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Tests\Adapter;

use PHPUnit\Framework\Attributes\Group;
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\Cache\Adapter\ArrayAdapter;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Cache\Adapter\Psr16Adapter;
use

impleCache cannot clear by prefix',
        'testClearPrefixWithUnderscore' => 'SimpleCache cannot clear by prefix',
    ];

    public function createCachePool(int $defaultLifetime = 0): CacheItemPoolInterface
    {
        return new Psr16Adapter(new Psr

 Symfony\Component\Cache\Psr16Cache;

#[Group('time-sensitive')]
class Psr16AdapterTest extends AdapterTestCase
{
    protected $skippedTests = [
        'testPrune' => 'Psr16adapter just proxies',
        'testClearPrefix' => 'S


buted with this source code.
 */

namespace Symfony\Component\Cache\Tests\Adapter;

use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Group;
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\Cache\Adapter\AbstractAdapter;
use Symfony\Component\Cache\Adapter\RedisAdapter;
use Symfony\Component\Cache\Exception\InvalidArgumentException;
use Symfony\Component\Cache\Traits\RedisProxy;

#[Group('integration')]
class RedisAdapterTest extends AbstractRedisAdapterTestCase
{

reateCachePool(int $defaultLifetime = 0, ?string $testMethod = null): CacheItemPoolInterface
    {
        if ('testClearWithPrefix' === $testMethod && \defined('Redis::SCAN_PREFIX')) {
            self::$redis->setOption(\Redis::OPT_SCAN, \Redis::SCAN_PRE

  public static function setUpBeforeClass(): void
    {
        parent::setUpBeforeClass();
        self::$redis = AbstractAdapter::createConnection('redis://'.getenv('REDIS_HOST'), ['lazy' => true]);
    }

    public function c


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Tests\Adapter;

use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Group;
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\Cache\Adapter\AbstractAdapter;
use Symfony\Component\Cache\Adapter\RedisAdapter;
use Symfony\Component\Cache\Exception\InvalidAr

  if (!class_exists(\RedisCluster::class)) {
            self::markTestSkipped('The RedisCluster class is required.');
        }
        if (!$hosts = getenv('REDIS_CLUSTER_HOSTS')) {
            self::markTestSkipped('REDIS_CLUSTER_HOSTS env var is not de

gumentException;
use Symfony\Component\Cache\Traits\RedisClusterProxy;

#[Group('integration')]
class RedisClusterAdapterTest extends AbstractRedisAdapterTestCase
{
    public static function setUpBeforeClass(): void
    {


/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Tests\Adapter;

use PHPUnit\Framework\Attributes\Group;
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\Cache\Adapter\RedisTagAwareAdapter;

#[Group('integration')]
class RedisTagAwareArrayAdapterTest extends RedisArrayAdapterTest
{

chePool(int $defaultLifetime = 0, ?string $testMethod = null): CacheItemPoolInterface
    {
        if ('testClearWithPrefix' === $testMethod && \defined('Redis::SCAN_PREFIX')) {
            self::$redis->setOption(\Redis::OPT_SCAN, \Redis::SCAN_PREFIX);

   use TagAwareTestTrait;

    protected function setUp(): void
    {
        parent::setUp();
        $this->skippedTests['testTagItemExpiry'] = 'Testing expiration slows down the test suite';
    }

    public function createCa


/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Tests\Adapter;

use PHPUnit\Framework\Attributes\Group;
use PHPUnit\Framework\Attributes\RequiresPhpExtension;
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\Cache\Adapter\RedisTagAwareAdapter;
use Symfony\Component\Cache\Traits\Rela

parent::setUp();
        $this->skippedTests['testTagItemExpiry'] = 'Testing expiration slows down the test suite';
    }

    public function createCachePool(int $defaultLifetime = 0, ?string $testMethod = null): CacheItemPoolInterface
    {
        $this

yClusterProxy;

#[RequiresPhpExtension('relay')]
#[Group('integration')]
class RedisTagAwareRelayClusterAdapterTest extends RelayClusterAdapterTest
{
    use TagAwareTestTrait;

    protected function setUp(): void
    {


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Tests\Adapter;

use PHPUnit\Framework\Attributes\Group;
use PHPUnit\Framework\Attributes\RequiresPhpExtension;
use Relay\Relay;
use Symfony\Component\Cache\Adapter\AbstractAdapter;
use Symfony\Component\Cache\Adapter\RedisAdapter;
use Symfony\Component\Cache\Except

BeforeClass(): void
    {
        try {
            new Relay(...explode(':', getenv('REDIS_HOST')));
        } catch (\Relay\Exception $e) {
            self::markTestSkipped(getenv('REDIS_HOST').': '.$e->getMessage());
        }
        self::$redis = Ab

ion\InvalidArgumentException;
use Symfony\Component\Cache\Traits\RelayProxy;

#[RequiresPhpExtension('relay')]
#[Group('integration')]
class RelayAdapterTest extends AbstractRedisAdapterTestCase
{
    public static function setUp


buted with this source code.
 */

namespace Symfony\Component\Cache\Tests\Adapter;

use PHPUnit\Framework\Attributes\DoesNotPerformAssertions;
use PHPUnit\Framework\Attributes\Group;
use PHPUnit\Framework\MockObject\MockObject;
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\Cache\Adapter\AdapterInterface;
use Symfony\Component\Cache\Adapter\ArrayAdapter;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Cache\Adapter\TagAwareAdapter;
use Symfony\Component\Cache\Prunea

  public function createCachePool($defaultLifetime = 0): CacheItemPoolInterface
    {
        return new TagAwareAdapter(new FilesystemAdapter('', $defaultLifetime));
    }

    public static function tearDownAfterClass(): void
    {
        (new Filesyste

bleInterface;
use Symfony\Component\Cache\Tests\Fixtures\PrunableAdapter;
use Symfony\Component\Filesystem\Filesystem;

#[Group('time-sensitive')]
class TagAwareAdapterTest extends AdapterTestCase
{
    use TagAwareTestTrait;


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Tests\Adapter;

use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\Cache\Adapter\ArrayAdapter;
use Symfony\Component\Cache\Adapter\ProxyAdapter;
use Symfony\Component\Cache\Adapter\TagAwareAdapter;
use S

face $proxiedAdapter)
    {
        $cache = new TagAwareAdapter(new ProxyAdapter($proxiedAdapter));

        $item = $cache->getItem('foo');
        $item->tag(['tag1', 'tag2']);
        $item->set('bar');
        $cache->save($item);

        $this->asse

ymfony\Component\Cache\Tests\Fixtures\ExternalAdapter;

class TagAwareAndProxyAdapterIntegrationTest extends TestCase
{
    #[DataProvider('dataProvider')]
    public function testIntegrationUsingProxiedAdapter(CacheItemPoolInter


hp

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Tests\Adapter;

use PHPUnit\Framework\Attributes\Group;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Cache\Adapter\TagAwareAdapter;
use Symfony\Component\Cache\Adapter\TraceableTagAwareAdapter;

#[Group('time-se

->invalidateTags(['foo']);
        $calls = $pool->getCalls();
        $this->assertCount(1, $calls);

        $call = $calls[0];
        $this->assertSame('invalidateTags', $call->name);
        $this->assertSame(0, $call->hits);
        $this->assertSame

nsitive')]
class TraceableTagAwareAdapterTest extends TraceableAdapterTest
{
    public function testInvalidateTags()
    {
        $pool = new TraceableTagAwareAdapter(new TagAwareAdapter(new FilesystemAdapter()));
        $pool


he Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Tests\Fixtures;

use Symfony\Component\Cache\Adapter\FilesystemTagAwareAdapter;

/**
 * Adapter that simulates a failure when saving tags.
 */
class FailingTagFilesystemAdapter extends FilesystemTagAwareAdapter
{
    protected function doSave(array $values, int $lifetime, ar

ray
    {
        $failed = parent::doSave($values, $lifetime, $addTagData, $removeTagData);

        // Simulate tag save failure by returning tag IDs as failed
        foreach ($addTagData as $tagId => $ids) {
            $failed[] = $tagId;
        }

ray $addTagData = [], array $removeTagData = []): ar


he Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Tests\Adapter;

use PHPUnit\Framework\Attributes\Group;
use Symfony\Component\Cache\Adapter\RedisAdapter;

#[Group('integration')]
class PredisRedisClusterAdapterTest extends AbstractRedisAdapterTestCase
{
    public static function setUpBeforeClass(): void
    {
        if

    self::markTestSkipped('REDIS_CLUSTER_HOSTS env var is not defined.');
        }

        self::$redis = RedisAdapter::createConnection('redis:?host['.str_replace(' ', ']&host[', $hosts).']', ['class' => \Predis\Client::class, 'redis_cluster' => true, '

(!$hosts = getenv('REDIS_CLUSTER_HOSTS')) {


?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Tests\Adapter;

use PHPUnit\Framework\Attributes\Group;
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\Cache\Adapter\RedisTagAwareAdapter;

#[Group('integration')]
class PredisTagAwareAdapterTest extends PredisAdapterTest
{

Pool(int $defaultLifetime = 0, ?string $testMethod = null): CacheItemPoolInterface
    {
        $this->assertInstanceOf(\Predis\Client::class, self::$redis);
        $adapter = new RedisTagAwareAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $def

use TagAwareTestTrait;

    protected function setUp(): void
    {
        parent::setUp();
        $this->skippedTests['testTagItemExpiry'] = 'Testing expiration slows down the test suite';
    }

    public function createCache


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Tests\Adapter;

use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Group;
use PHPUnit\Framework\Attributes\RequiresPhpExtension;
use Psr\Cache\CacheItemPoolInterface;
use Relay\Cluster as RelayCluster;
use Relay\Relay;
use Symfony\Component\Cache\Adapter\Abstrac

ion')]
class RelayClusterAdapterTest extends AbstractRedisAdapterTestCase
{
    public static function setUpBeforeClass(): void
    {
        if (!class_exists(RelayCluster::class)) {
            self::markTestSkipped('The Relay\Cluster class is required.'

tAdapter;
use Symfony\Component\Cache\Adapter\RedisAdapter;
use Symfony\Component\Cache\Exception\InvalidArgumentException;
use Symfony\Component\Cache\Traits\RelayClusterProxy;

#[RequiresPhpExtension('relay')]
#[Group('integrat


buted with this source code.
 */

namespace Symfony\Component\Cache\Tests\Adapter;

use PHPUnit\Framework\Attributes\Group;
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Cache\Adapter\TraceableAdapter;

#[Group('time-sensitive')]
class TraceableAdapterTest extends AdapterTestCase
{
    protected $skippedTests = [
        'testPrune' => 'TraceableAdapter just proxies',
    ];

    public function createCachePool(int $defaultLifetime = 0): C

m('k');
        $calls = $pool->getCalls();
        $this->assertCount(1, $calls);

        $call = $calls[0];
        $this->assertSame('getItem', $call->name);
        $this->assertSame(['k' => false], $call->result);
        $this->assertSame(0, $call->

acheItemPoolInterface
    {
        return new TraceableAdapter(new FilesystemAdapter('', $defaultLifetime));
    }

    public function testGetItemMissTrace()
    {
        $pool = $this->createCachePool();
        $pool->getIte


quiresPhpExtension;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Cache\Exception\InvalidArgumentException;
use Symfony\Component\Cache\Traits\RedisTrait;

#[RequiresPhpExtension('redis')]
class RedisTraitTest extends TestCase
{
    public static function setUpBeforeClass(): void
    {
        try {
            (new \Redis())->connect(...explode(':', getenv('REDIS_HOST')));
        } catch (\Exception $e) {
            self::markTestSkipped(getenv('REDIS_HOST').': '.$e->getMessage());
        }

" class is required.', $expectedClass));
        }
        if (!getenv('REDIS_CLUSTER_HOSTS')) {
            self::markTestSkipped('REDIS_CLUSTER_HOSTS env var is not defined.');
        }

        $mock = new class {
            use RedisTrait;
        };

}

    #[DataProvider('provideCreateConnection')]
    public function testCreateConnection(string $dsn, string $expectedClass)
    {
        if (!class_exists($expectedClass)) {
            self::markTestSkipped(\sprintf('The "%s


hp

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Tests\Adapter;

use PHPUnit\Framework\Attributes\Group;
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\Cache\Adapter\RedisTagAwareAdapter;

#[Group('integration')]
class PredisTagAwareReplicationAdapterTest extends PredisRedisRepl

blic function createCachePool(int $defaultLifetime = 0, ?string $testMethod = null): CacheItemPoolInterface
    {
        $this->assertInstanceOf(\Predis\Client::class, self::$redis);
        $adapter = new RedisTagAwareAdapter(self::$redis, str_replace('\

icationAdapterTest
{
    use TagAwareTestTrait;

    protected function setUp(): void
    {
        parent::setUp();
        $this->skippedTests['testTagItemExpiry'] = 'Testing expiration slows down the test suite';
    }

    pu


s part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Tests\Adapter;

use PHPUnit\Framework\Attributes\Group;

#[Group('integration')]
class RedisArrayAdapterTest extends AbstractRedisAdapterTestCase
{
    public static function setUpBeforeClass(): void
    {
        parent::setUpBeforeClass();
        if (!class_exi

y::class)) {
            self::markTestSkipped('The RedisArray class is required.');
        }
        self::$redis = new \RedisArray([getenv('REDIS_HOST')], ['lazy_connect' => true]);
        self::$redis->setOption(\Redis::OPT_PREFIX, 'prefix_');
    }
}


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Tests\Adapter;

use PHPUnit\Framework\Attributes\Group;
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\Cache\Adapter\RedisTagAwareAdapter;
use Symfony\Component\Cache\Traits\RedisClusterProxy;

#[Group('integration')]
class RedisTagAwareCl

the test suite';
    }

    public function createCachePool(int $defaultLifetime = 0, ?string $testMethod = null): CacheItemPoolInterface
    {
        if ('testClearWithPrefix' === $testMethod && \defined('Redis::SCAN_PREFIX')) {
            self::$redis-

usterAdapterTest extends RedisClusterAdapterTest
{
    use TagAwareTestTrait;

    protected function setUp(): void
    {
        parent::setUp();
        $this->skippedTests['testTagItemExpiry'] = 'Testing expiration slows down


/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Tests\Adapter;

use PHPUnit\Framework\Attributes\Group;

#[Group('integration')]
class PredisReplicationAdapterTest extends AbstractRedisAdapterTestCase
{
    public static function setUpBeforeClass(): void
    {
        parent::setUpBeforeClass(

     $lastArrayKey = array_key_last($hosts);
        $hostTable = [];
        foreach ($hosts as $key => $host) {
            $hostInformation = array_combine(['host', 'port'], explode(':', $host));
            if ($lastArrayKey === $key) {

);

        if (!$hosts = getenv('REDIS_REPLICATION_HOSTS')) {
            self::markTestSkipped('REDIS_REPLICATION_HOSTS env var is not defined.');
        }

        $hosts = explode(' ', getenv('REDIS_REPLICATION_HOSTS'));


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\TypeInfo\TypeResolver;

use Symfony\Component\TypeInfo\Exception\InvalidArgumentException;
use Symfony\Component\TypeInfo\Exception\UnsupportedException;
use Symfony\Component\TypeInfo\Type;
use Symfony\Component\TypeInfo\TypeContext\TypeContext;
use Symfony\Component\TypeInfo\TypeIdentifier;

/**
 * Resolves type for a given type reflection.
 *

Context $typeContext = null): Type
    {
        if ($subject instanceof \ReflectionUnionType) {
            return Type::union(...array_map(fn (mixed $t): Type => $this->resolve($t, $typeContext), $subject->getTypes()));
        }

        if ($subject in

 * @author Mathias Arlaud <mathias.arlaud@gmail.com>
 * @author Baptiste Leduc <baptiste.leduc@gmail.com>
 */
final class ReflectionTypeResolver implements TypeResolverInterface
{
    public function resolve(mixed $subject, ?Type


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\TypeInfo\TypeResolver;

use Symfony\Component\TypeInfo\Exception\UnsupportedException;
use Symfony\Component\TypeInfo\Type;
use Symfony\Component\TypeInfo\TypeContext\TypeContext;
use Symfony\Component\TypeInfo\TypeContext\TypeContextFactory;

/**
 * Resolves return type

blic function __construct(
        private readonly ReflectionTypeResolver $reflectionTypeResolver,
        private readonly TypeContextFactory $typeContextFactory,
    ) {
    }

    public function resolve(mixed $subject, ?TypeContext $typeContext = null

 for a given function reflection.
 *
 * @author Mathias Arlaud <mathias.arlaud@gmail.com>
 * @author Baptiste Leduc <baptiste.leduc@gmail.com>
 */
final class ReflectionReturnTypeResolver implements TypeResolverInterface
{
    pu


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\TypeInfo\Tests\TypeResolver;

use PHPUnit\Framework\TestCase;
use Symfony\Component\TypeInfo\Exception\UnsupportedException;
use Symfony\Component\TypeInfo\Tests\Fixtures\ReflectionExtractableDummy;
use Symfony\Component\TypeInfo\Tests\Fixtures\ReflectionExtractableDummyUsingTrait;
use Symfony\Component\TypeInfo\Tests\Fixtures\ReflectionExtractab

ReflectionTypeResolver;

class ReflectionPropertyTypeResolverTest extends TestCase
{
    private ReflectionPropertyTypeResolver $resolver;

    protected function setUp(): void
    {
        $this->resolver = new ReflectionPropertyTypeResolver(new Reflecti

leTrait;
use Symfony\Component\TypeInfo\Type;
use Symfony\Component\TypeInfo\TypeContext\TypeContextFactory;
use Symfony\Component\TypeInfo\TypeResolver\ReflectionPropertyTypeResolver;
use Symfony\Component\TypeInfo\TypeResolver\


flectionTypeResolver;

class ReflectionReturnTypeResolverTest extends TestCase
{
    private ReflectionReturnTypeResolver $resolver;

    protected function setUp(): void
    {
        $this->resolver = new ReflectionReturnTypeResolver(new ReflectionTypeRe

leTrait;
use Symfony\Component\TypeInfo\Type;
use Symfony\Component\TypeInfo\TypeContext\TypeContextFactory;
use Symfony\Component\TypeInfo\TypeResolver\ReflectionReturnTypeResolver;
use Symfony\Component\TypeInfo\TypeResolver\Re


buted with this source code.
 */

namespace Symfony\Component\TypeInfo\Tests\TypeResolver;

use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Symfony\Component\TypeInfo\Exception\InvalidArgumentException;
use Symfony\Component\TypeInfo\Exception\UnsupportedException;
use Symfony\Component\TypeInfo\Tests\Fixtures\AbstractDummy;
use Symfony\Component\TypeInfo\Tests\Fixtures\Dummy;
use Symfony\Component\TypeInfo\Tests\Fixtures\DummyBackedEnum;
use Symfony\Component\TypeInfo\Tes

ypeInfo\TypeContext\TypeContext;
use Symfony\Component\TypeInfo\TypeContext\TypeContextFactory;
use Symfony\Component\TypeInfo\TypeResolver\ReflectionTypeResolver;

class ReflectionTypeResolverTest extends TestCase
{
    private ReflectionTypeResolver $res

ts\Fixtures\DummyBackedEnumInterface;
use Symfony\Component\TypeInfo\Tests\Fixtures\DummyEnum;
use Symfony\Component\TypeInfo\Tests\Fixtures\ReflectionExtractableDummy;
use Symfony\Component\TypeInfo\Type;
use Symfony\Component\T


eption\InvalidArgumentException;
use Symfony\Component\TypeInfo\Exception\UnsupportedException;
use Symfony\Component\TypeInfo\Tests\Fixtures\AbstractDummy;
use Symfony\Component\TypeInfo\Tests\Fixtures\Dummy;
use Symfony\Component\TypeInfo\Tests\Fixtures\DummyBackedEnum;
use Symfony\Component\TypeInfo\Tests\Fixtures\DummyBackedEnumInterface;
use Symfony\Component\TypeInfo\Tests\Fixtures\DummyCollection;
use Symfony\Component\TypeInfo\Tests\Fixtures\DummyEnum;
use Symfony\Component\TypeInfo\Tests\Fixtures\D

e Symfony\Component\TypeInfo\Type;
use Symfony\Component\TypeInfo\TypeContext\TypeContext;
use Symfony\Component\TypeInfo\TypeContext\TypeContextFactory;
use Symfony\Component\TypeInfo\TypeResolver\StringTypeResolver;

class StringTypeResolverTest extends

ummyWithConstants;
use Symfony\Component\TypeInfo\Tests\Fixtures\DummyWithTemplates;
use Symfony\Component\TypeInfo\Tests\Fixtures\DummyWithTemplateTypeAlias;
use Symfony\Component\TypeInfo\Tests\Fixtures\DummyWithTypeAliases;
us


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\TypeInfo\Tests\TypeResolver;

use PHPUnit\Framework\TestCase;
use Symfony\Component\TypeInfo\Exception\UnsupportedException;
use Symfony\Component\TypeInfo\Tests\Fixtures\Dummy;
use Symfony\Component\TypeInfo\Type;
use Symfony\Component\TypeInfo\TypeResolver\TypeResolver;
use Symfony\Component\TypeInfo\TypeResolver\TypeResolverInterface;

class T

), $resolver->resolve((new \ReflectionProperty(Dummy::class, 'id'))->getType()));
        $this->assertEquals(Type::int(), $resolver->resolve((new \ReflectionMethod(Dummy::class, 'setId'))->getParameters()[0]));
        $this->assertEquals(Type::int(), $re

ypeResolverTest extends TestCase
{
    public function testResolve()
    {
        $resolver = TypeResolver::create();

        $this->assertEquals(Type::bool(), $resolver->resolve('bool'));
        $this->assertEquals(Type::int(


?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\TypeInfo\Tests\Fixtures;

final class DummyWithConstants
{
    public const DUMMY_STRING_A = 'a';
    public const DUMMY_INT_A = 1;
    public const DUMMY_FLOAT_A = 1.23;
    public const DUMMY_TRUE_A = true;
    public const DUMMY_FALSE_A = false

    public const DUMMY_MIX_3 = self::DUMMY_FLOAT_A;
    public const DUMMY_MIX_4 = self::DUMMY_TRUE_A;
    public const DUMMY_MIX_5 = self::DUMMY_FALSE_A;
    public const DUMMY_MIX_6 = self::DUMMY_NULL_A;
    public const DUMMY_MIX_7 = self::DUMMY_ARRAY_A

;
    public const DUMMY_NULL_A = null;
    public const DUMMY_ARRAY_A = [];
    public const DUMMY_ENUM_A = DummyEnum::ONE;

    public const DUMMY_MIX_1 = self::DUMMY_STRING_A;
    public const DUMMY_MIX_2 = self::DUMMY_INT_A;


hp

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\TypeInfo\Tests\Fixtures;

/**
 * @phpstan-type CustomInt = int
 * @psalm-type PsalmCustomInt = int
 */
final class DummyWithPhpDoc
{
    /**
     * @var array<Dummy>
     */
    public mixed $arrayOfDummies = [];

    /**
     * @var CustomInt

/
        public mixed $promotedVar,
        /**
         * @var string
         */
        public mixed $promotedVarAndParam,
    ) {
    }

    /**
     * @param Dummy $dummy
     *
     * @return Dummy
     */
    public function getNextDummy(mixed $dum

*/
    public mixed $aliasedInt;

    /**
     * @param bool $promoted
     * @param bool $promotedVarAndParam
     */
    public function __construct(
        public mixed $promoted,
        /**
         * @var string
         *


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\TypeInfo\Tests\Fixtures;

/**
 * @phpstan-type CustomArray = array{0: CustomInt, 1: CustomString, 2: bool}
 * @phpstan-type CustomString = string
 *
 * @phpstan-import-type CustomInt from DummyWithPhpDoc
 * @phpstan-import-type CustomInt from DummyWithPhpDoc as AliasedCu

lmCustomInt from DummyWithPhpDoc as PsalmAliasedCustomInt
 */
final class DummyWithTypeAliases
{
    /**
     * @var CustomString
     */
    public mixed $localAlias;

    /**
     * @var CustomInt
     */
    public mixed $externalAlias;

    /**
     *

stomInt
 *
 * @psalm-type PsalmCustomArray = array{0: PsalmCustomInt, 1: PsalmCustomString, 2: bool}
 * @psalm-type PsalmCustomString = string
 *
 * @psalm-import-type PsalmCustomInt from DummyWithPhpDoc
 * @psalm-import-type Psa


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\TypeInfo\Tests\Fixtures;

final class ReflectionExtractableDummy extends AbstractDummy
{
    public int $builtin;
    public ?int $nullableBuiltin;

    public array $array;
    public ?array $nullableArray;

    public iterable $iterable;
    public ?iterable $nullableI

?DummyEnum $nullableEnum;

    public DummyBackedEnum $backedEnum;
    public ?DummyBackedEnum $nullableBackedEnum;

    public DummyBackedEnumInterface $backedEnumInterface;

    public int|string $union;
    public \Traversable&\Stringable $intersection;

terable;

    public Dummy $class;
    public ?Dummy $nullableClass;

    public self $self;
    public ?self $nullableSelf;

    public parent $parent;
    public ?parent $nullableParent;

    public DummyEnum $enum;
    public


buted with this source code.
 */

namespace Symfony\Component\TypeInfo\Tests\Type;

use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Symfony\Component\TypeInfo\Exception\InvalidArgumentException;
use Symfony\Component\TypeInfo\Type;
use Symfony\Component\TypeInfo\Type\ArrayShapeType;

class ArrayShapeTypeTest extends TestCase
{
    #[DataProvider('cannotConstructWithInvalidExtraDataProvider')]
    public function testCannotConstructWithInvalidExtra(string $expectedMessage,

ype' => Type::bool(), 'optional' => false]],
            extraKeyType: $extraKeyType,
            extraValueType: $extraValueType,
        );
    }

    /**
     * @return iterable<array{0: string, 1: ?Type, 2: ?Type}>
     */
    public static function ca

?Type $extraKeyType, ?Type $extraValueType)
    {
        $this->expectException(InvalidArgumentException::class);
        $this->expectExceptionMessage($expectedMessage);

        new ArrayShapeType(
            shape: [1 => ['t


/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\TypeInfo\Tests\Type;

use PHPUnit\Framework\TestCase;
use Symfony\Component\TypeInfo\Exception\InvalidArgumentException;
use Symfony\Component\TypeInfo\Tests\Fixtures\DummyBackedEnum;
use Symfony\Component\TypeInfo\Type;
use Symfony\Component\TypeInfo\

ummyBackedEnum::class, Type::bool());
    }

    public function testToString()
    {
        $this->assertSame(DummyBackedEnum::class, (string) new BackedEnumType(DummyBackedEnum::class, Type::int()));
    }

    public function testAccepts()
    {

Type\BackedEnumType;

class BackedEnumTypeTest extends TestCase
{
    public function testCannotCreateInvalidBackingBuiltinType()
    {
        $this->expectException(InvalidArgumentException::class);
        new BackedEnumType(D


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\TypeInfo\Tests\Type;

use PHPUnit\Framework\TestCase;
use Symfony\Component\TypeInfo\Type\BuiltinType;
use Symfony\Component\TypeInfo\TypeIdentifier;

class BuiltinTypeTest extends TestCase
{
    public function testToString()
    {
        $this->assertSame('int', (string) new BuiltinType(TypeIdentifier::INT));
    }

    public function testIsI

;

        $this->assertFalse((new BuiltinType(TypeIdentifier::INT))->isIdentifiedBy('array'));
        $this->assertTrue((new BuiltinType(TypeIdentifier::INT))->isIdentifiedBy('int'));

        $this->assertTrue((new BuiltinType(TypeIdentifier::INT))->isI

dentifiedBy()
    {
        $this->assertFalse((new BuiltinType(TypeIdentifier::INT))->isIdentifiedBy(TypeIdentifier::ARRAY));
        $this->assertTrue((new BuiltinType(TypeIdentifier::INT))->isIdentifiedBy(TypeIdentifier::INT))


buted with this source code.
 */

namespace Symfony\Component\TypeInfo\Tests\Type;

use PHPUnit\Framework\TestCase;
use Symfony\Component\TypeInfo\Exception\InvalidArgumentException;
use Symfony\Component\TypeInfo\Type;
use Symfony\Component\TypeInfo\Type\CollectionType;
use Symfony\Component\TypeInfo\Type\GenericType;
use Symfony\Component\TypeInfo\TypeIdentifier;

class CollectionTypeTest extends TestCase
{
    public function testCannotCreateInvalidBuiltinType()
    {
        $this->expectException(Inval

int(), Type::bool()), isList: true);
        $this->addToAssertionCount(1);

        $this->expectException(InvalidArgumentException::class);
        new CollectionType(Type::generic(Type::builtin(TypeIdentifier::ARRAY), Type::string(), Type::bool()), isLi

idArgumentException::class);
        new CollectionType(Type::int());
    }

    public function testCanOnlyConstructListWithIntKeyType()
    {
        new CollectionType(Type::generic(Type::builtin(TypeIdentifier::ARRAY), Type::


s part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\TypeInfo\Tests\Type;

use PHPUnit\Framework\TestCase;
use Symfony\Component\TypeInfo\Tests\Fixtures\DummyEnum;
use Symfony\Component\TypeInfo\Type\EnumType;

class EnumTypeTest extends TestCase
{
    public function testToString()
    {
        $this->assertSame(DummyEn

ring) new EnumType(DummyEnum::class));
    }

    public function testAccepts()
    {
        $type = new EnumType(DummyEnum::class);

        $this->assertFalse($type->accepts('string'));
        $this->assertTrue($type->accepts(DummyEnum::ONE));
    }
}


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\TypeInfo\Tests\Type;

use PHPUnit\Framework\TestCase;
use Symfony\Component\TypeInfo\Exception\InvalidArgumentException;
use Symfony\Component\TypeInfo\Type;
use Symfony\Component\TypeInfo\Type\GenericType;
use Symfony\Component\TypeInfo\TypeIdentifier;

class GenericTypeTest extends TestCase
{

        $type = new GenericType(Type::builtin(TypeIdentifier::ARRAY), Type::bool());
        $this->assertEquals('array<bool>', (string) $type);

        $type = new GenericType(Type::builtin(TypeIdentifier::ARRAY), Type::string(), Type::bool());
        $

   public function testCannotCreateInvalidBuiltinType()
    {
        $this->expectException(InvalidArgumentException::class);
        new GenericType(Type::int(), Type::string());
    }

    public function testToString()
    {


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\TypeInfo\Tests\Type;

use PHPUnit\Framework\TestCase;
use Symfony\Component\TypeInfo\Exception\InvalidArgumentException;
use Symfony\Component\TypeInfo\Type;
use Symfony\Component\TypeInfo\Type\IntersectionType;
use Symfony\Component\TypeInfo\Type\ObjectType;
use Symfony\Component\TypeInfo\Type\UnionType;

class IntersectionTypeTest extends TestC

tCreateWithUnionTypePart()
    {
        $this->expectException(InvalidArgumentException::class);
        new IntersectionType(Type::object(\DateTime::class), new UnionType(Type::int(), Type::string()));
    }

    public function testCannotCreateWithInter

ase
{
    public function testCannotCreateWithOnlyOneType()
    {
        $this->expectException(InvalidArgumentException::class);
        new IntersectionType(Type::object(\DateTime::class));
    }

    public function testCanno


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\TypeInfo\Tests\Type;

use PHPUnit\Framework\TestCase;
use Symfony\Component\TypeInfo\Exception\InvalidArgumentException;
use Symfony\Component\TypeInfo\Type;
use Symfony\Component\TypeInfo\Type\NullableType;

class NullableTypeTest extends TestCase
{
    public function

Type(Type::int());
        $this->assertEquals([Type::int(), Type::null()], $type->getTypes());

        $type = new NullableType(Type::union(Type::int(), Type::string()));
        $this->assertEquals([Type::int(), Type::null(), Type::string()], $type->get

testCannotCreateWithNullableType()
    {
        $this->expectException(InvalidArgumentException::class);
        new NullableType(Type::null());
    }

    public function testNullPartIsAdded()
    {
        $type = new Nullable


buted with this source code.
 */

namespace Symfony\Component\TypeInfo\Tests\Type;

use PHPUnit\Framework\TestCase;
use Symfony\Component\TypeInfo\Type;
use Symfony\Component\TypeInfo\Type\ObjectShapeType;
use Symfony\Component\TypeInfo\TypeIdentifier;

class ObjectShapeTypeTest extends TestCase
{
    public function testGetTypeIdentifier()
    {
        $type = new ObjectShapeType(['foo' => ['type' => Type::bool(), 'optional' => false]]);
        $this->assertSame(TypeIdentifier::OBJECT, $type->getTypeIden

bool(), 'optional' => false],
            'bar' => ['type' => Type::string(), 'optional' => true],
        ];

        $type = new ObjectShapeType($shape);
        ksort($shape);

        $this->assertSame($shape, $type->getShape());
    }

    public func

tifier());

        $this->assertSame(TypeIdentifier::OBJECT, (new ObjectShapeType([]))->getTypeIdentifier());
    }

    public function testGetShapeIsSortedByKey()
    {
        $shape = [
            'foo' => ['type' => Type::


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\TypeInfo\Tests\Type;

use PHPUnit\Framework\TestCase;
use Symfony\Component\TypeInfo\Type\ObjectType;
use Symfony\Component\TypeInfo\TypeIdentifier;

class ObjectTypeTest extends TestCase
{
    public function testToString()
    {
        $this->assertSame(self::class, (

pe(self::class))->isIdentifiedBy(TypeIdentifier::OBJECT));

        $this->assertFalse((new ObjectType(self::class))->isIdentifiedBy('array'));
        $this->assertTrue((new ObjectType(self::class))->isIdentifiedBy('object'));

        $this->assertTrue((

string) new ObjectType(self::class));
    }

    public function testIsIdentifiedBy()
    {
        $this->assertFalse((new ObjectType(self::class))->isIdentifiedBy(TypeIdentifier::ARRAY));
        $this->assertTrue((new ObjectTy


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\TypeInfo\Tests\Type;

use PHPUnit\Framework\TestCase;
use Symfony\Component\TypeInfo\Exception\InvalidArgumentException;
use Symfony\Component\TypeInfo\Type;
use Symfony\Component\TypeInfo\Type\BuiltinType;
use Symfony\Component\TypeInfo\Type\ObjectType;
use Symfony\Component\TypeInfo\Type\UnionType;

class UnionTypeTest extends TestCase
{
    pu

   $this->expectException(InvalidArgumentException::class);
        new UnionType(Type::int(), new UnionType());
    }

    public function testCannotCreateWithNullPart()
    {
        $this->expectException(InvalidArgumentException::class);
        new Un

blic function testCannotCreateWithOnlyOneType()
    {
        $this->expectException(InvalidArgumentException::class);
        new UnionType(Type::int());
    }

    public function testCannotCreateWithUnionTypePart()
    {


ption\LogicException;
use Symfony\Component\TypeInfo\Tests\Fixtures\AbstractDummy;
use Symfony\Component\TypeInfo\Tests\Fixtures\AnotherNamespace\DummyInDifferentNs;
use Symfony\Component\TypeInfo\Tests\Fixtures\AnotherNamespace\DummyWithTemplateAndParentInDifferentNs;
use Symfony\Component\TypeInfo\Tests\Fixtures\Dummy;
use Symfony\Component\TypeInfo\Tests\Fixtures\DummyWithImportedOnlyTypeAliases;
use Symfony\Component\TypeInfo\Tests\Fixtures\DummyWithInvalidTypeAlias;
use Symfony\Component\TypeInfo\Tests

res\DummyWithRecursiveTypeAliases;
use Symfony\Component\TypeInfo\Tests\Fixtures\DummyWithTemplateAndParent;
use Symfony\Component\TypeInfo\Tests\Fixtures\DummyWithTemplates;
use Symfony\Component\TypeInfo\Tests\Fixtures\DummyWithTemplateTypeAlias;
use Sym

\Fixtures\DummyWithInvalidTypeAliasImport;
use Symfony\Component\TypeInfo\Tests\Fixtures\DummyWithPhpstanTemplates;
use Symfony\Component\TypeInfo\Tests\Fixtures\DummyWithPsalmTemplates;
use Symfony\Component\TypeInfo\Tests\Fixtu


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\TypeInfo\Tests\TypeContext;

use PHPUnit\Framework\TestCase;
use Symfony\Component\TypeInfo\Exception\LogicException;
use Symfony\Component\TypeInfo\Tests\Fixtures\AbstractDummy;
use Symfony\Component\TypeInfo\Tests\Fixtures\AnotherNamespace\DummyInDifferentNs;
use Symfony\Component\TypeInfo\Tests\Fixtures\Dummy;
use Symfony\Component\TypeInfo\Te

text\TypeContextFactory;

class TypeContextTest extends TestCase
{
    public function testNormalize()
    {
        $typeContext = (new TypeContextFactory())->createFromClassName(DummyWithUses::class);

        $this->assertSame(DummyWithUses::class, $typ

sts\Fixtures\DummyExtendingStdClass;
use Symfony\Component\TypeInfo\Tests\Fixtures\DummyWithUses;
use Symfony\Component\TypeInfo\Type;
use Symfony\Component\TypeInfo\TypeContext\TypeContext;
use Symfony\Component\TypeInfo\TypeCon


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\TypeInfo\TypeContext;

use Symfony\Component\TypeInfo\Exception\LogicException;
use Symfony\Component\TypeInfo\Type;

/**
 * Type resolving context.
 *
 * Helps to retrieve declaring class, called class, parent class, templates
 * and normalize classes according to the current namespace and uses.
 *
 * @author Mathias Arlaud <mathias.arlaud@gmail

 $uses
     * @param array<string, Type>   $templates
     * @param array<string, Type>   $typeAliases
     */
    public function __construct(
        public readonly string $calledClassName,
        public readonly string $declaringClassName,
        pub

.com>
 * @author Baptiste Leduc <baptiste.leduc@gmail.com>
 */
final class TypeContext
{
    /**
     * @var array<string, bool>
     */
    private static array $classExistCache = [];

    /**
     * @param array<string, string>


pDocParser\Ast\PhpDoc\TypeAliasImportTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\TypeAliasTagValueNode;
use PHPStan\PhpDocParser\Lexer\Lexer;
use PHPStan\PhpDocParser\Parser\ConstExprParser;
use PHPStan\PhpDocParser\Parser\PhpDocParser;
use PHPStan\PhpDocParser\Parser\TokenIterator;
use PHPStan\PhpDocParser\Parser\TypeParser;
use PHPStan\PhpDocParser\ParserConfig;
use Symfony\Component\TypeInfo\Exception\LogicException;
use Symfony\Component\TypeInfo\Exception\RuntimeException;
use Symfony\Component\T

.
 *
 * @author Mathias Arlaud <mathias.arlaud@gmail.com>
 * @author Baptiste Leduc <baptiste.leduc@gmail.com>
 * @author Pierre-Yves Landuré <landure@gmail.com>
 */
final class TypeContextFactory
{
    /**
     * @var array<class-string, \ReflectionClass>

ypeInfo\Exception\UnsupportedException;
use Symfony\Component\TypeInfo\Type;
use Symfony\Component\TypeInfo\Type\ObjectType;
use Symfony\Component\TypeInfo\TypeResolver\StringTypeResolver;

/**
 * Creates a type resolving context


buted with this source code.
 */

namespace Symfony\Component\EventDispatcher;

use Psr\EventDispatcher\StoppableEventInterface;
use Symfony\Component\EventDispatcher\Debug\WrappedListener;

/**
 * The EventDispatcherInterface is the central point of Symfony's event listener system.
 *
 * Listeners are registered on the manager and events are dispatched through the
 * manager.
 *
 * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
 * @author Jonathan Wage <jonwage@gmail.com>
 * @author Roman Borschel

thor Nicolas Grekas <p@tchwork.com>
 */
class EventDispatcher implements EventDispatcherInterface
{
    private array $listeners = [];
    private array $sorted = [];
    private array $optimized;

    public function __construct()
    {
        if (__CLAS

<roman@code-factory.org>
 * @author Bernhard Schussek <bschussek@gmail.com>
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Jordi Boggiano <j.boggiano@seld.be>
 * @author Jordan Alliot <jordan.alliot@gmail.com>
 * @au


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\EventDispatcher;

use Symfony\Contracts\EventDispatcher\EventDispatcherInterface as ContractsEventDispatcherInterface;

/**
 * The EventDispatcherInterface is the central point of Symfony's event listener system.
 * Listeners are registered on the manager and events are dispatched through the
 *

     * @param int $priority The higher this value, the earlier an event
     *                      listener will be triggered in the chain (defaults to 0)
     */
    public function addListener(string $eventName, callable $listener, int $priority = 0): v

manager.
 *
 * @author Bernhard Schussek <bschussek@gmail.com>
 */
interface EventDispatcherInterface extends ContractsEventDispatcherInterface
{
    /**
     * Adds an event listener that listens on the specified events.
     *


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\EventDispatcher;

/**
 * An EventSubscriber knows itself what events it is interested in.
 * If an EventSubscriber is added to an EventDispatcherInterface, the manager invokes
 * {@link getSubscribedEvents} and registers the subscriber as a listener for all
 * returned e

EventSubscriberInterface
{
    /**
     * Returns an array of event names this subscriber wants to listen to.
     *
     * The array keys are event names and the value can be:
     *
     *  * The method name to call (priority defaults to 0)
     *  * An

vents.
 *
 * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
 * @author Jonathan Wage <jonwage@gmail.com>
 * @author Roman Borschel <roman@code-factory.org>
 * @author Bernhard Schussek <bschussek@gmail.com>
 */
interface


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\EventDispatcher;

use Symfony\Contracts\EventDispatcher\Event;

/**
 * Event encapsulation class.
 *
 * Encapsulates events thus decoupling the observer from the subject they encapsulate.
 *
 * @author Drak <drak@zikula.org>
 *
 * @implements \ArrayAccess<string, mixed>
 * @implements \IteratorAggregate<string, mixed>
 */
class GenericEvent exten

m array $arguments Arguments to store in the event
     */
    public function __construct(
        protected mixed $subject = null,
        protected array $arguments = [],
    ) {
    }

    /**
     * Getter for subject property.
     */
    public func

ds Event implements \ArrayAccess, \IteratorAggregate
{
    /**
     * Encapsulate an event with $subject and $arguments.
     *
     * @param mixed $subject   The subject of the event, usually an object or a callable
     * @para


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\EventDispatcher;

/**
 * A read-only proxy for an event dispatcher.
 *
 * @author Bernhard Schussek <bschussek@gmail.com>
 */
class ImmutableEventDispatcher implements EventDispatcherInterface
{
    public function __construct(
        private EventDispatcherInterface $d

me, callable|array $listener, int $priority = 0): never
    {
        throw new \BadMethodCallException('Unmodifiable event dispatchers must not be modified.');
    }

    public function addSubscriber(EventSubscriberInterface $subscriber): never
    {

ispatcher,
    ) {
    }

    public function dispatch(object $event, ?string $eventName = null): object
    {
        return $this->dispatcher->dispatch($event, $eventName);
    }

    public function addListener(string $eventNa


hp

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\EventDispatcher\Attribute;

/**
 * Service tag to autoconfigure event listeners.
 *
 * @author Alexander M. Turek <me@derrabus.de>
 */
#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
class AsEventListe

is listener if several are declared for the same event
     * @param string|null $dispatcher The service id of the event dispatcher to listen to
     */
    public function __construct(
        public ?string $event = null,
        public ?string $method =

ner
{
    /**
     * @param string|null $event      The event name to listen to
     * @param string|null $method     The method to run when the listened event is triggered
     * @param int         $priority   The priority of th


dispatcher = $this->createEventDispatcher();
        $this->listener = new TestEventListener();
    }

    protected function createEventDispatcher()
    {
        return new EventDispatcher();
    }

    public function testInitialState()
    {
        $this->assertEquals([], $this->dispatcher->getListeners());
        $this->assertFalse($this->dispatcher->hasListeners(self::preFoo));
        $this->assertFalse($this->dispatcher->hasListeners(self::postFoo));
    }

    public function testAddListener()

        $this->assertTrue($this->dispatcher->hasListeners(self::preFoo));
        $this->assertTrue($this->dispatcher->hasListeners(self::postFoo));
        $this->assertCount(1, $this->dispatcher->getListeners(self::preFoo));
        $this->assertCount(1,

  {
        $this->dispatcher->addListener('pre.foo', [$this->listener, 'preFoo']);
        $this->dispatcher->addListener('post.foo', $this->listener->postFoo(...));
        $this->assertTrue($this->dispatcher->hasListeners());


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\TypeInfo\TypeResolver;

use PHPStan\PhpDocParser\Parser\PhpDocParser;
use Psr\Container\ContainerInterface;
use Symfony\Component\TypeInfo\Exception\UnsupportedException;
use Symfony\Component\TypeInfo\Type;
use Symfony\Component\TypeInfo\TypeContext\TypeContext;
use Symfony\Component\TypeInfo\TypeContext\TypeContextFactory;

/**
 * Resolves type

verInterface
{
    /**
     * @param ContainerInterface $resolvers Locator of type resolvers, keyed by supported subject type
     */
    public function __construct(
        private readonly ContainerInterface $resolvers,
    ) {
    }

    public functio

 for a given subject by delegating resolving to nested type resolvers.
 *
 * @author Mathias Arlaud <mathias.arlaud@gmail.com>
 * @author Baptiste Leduc <baptiste.leduc@gmail.com>
 */
final class TypeResolver implements TypeResol


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\TypeInfo\Type;

use Symfony\Component\TypeInfo\Exception\InvalidArgumentException;
use Symfony\Component\TypeInfo\Type;
use Symfony\Component\TypeInfo\TypeIdentifier;

/**
 * Represents the exact shape of an array.
 *
 * @author Mathias Arlaud <mathias.arlaud@gmail.com>
 *
 * @extends CollectionType<GenericType<BuiltinType<TypeIdentifier::ARRAY>>

ape
     */
    public function __construct(
        array $shape,
        private readonly ?Type $extraKeyType = null,
        private readonly ?Type $extraValueType = null,
    ) {
        $keyTypes = [];
        $valueTypes = [];

        foreach ($shap

>
 */
final class ArrayShapeType extends CollectionType
{
    /**
     * @var array<array{type: Type, optional: bool}>
     */
    private readonly array $shape;

    /**
     * @param array<array{type: Type, optional: bool}> $sh


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\TypeInfo\Type;

use Symfony\Component\TypeInfo\Type;
use Symfony\Component\TypeInfo\TypeIdentifier;

/**
 * @author Mathias Arlaud <mathias.arlaud@gmail.com>
 * @author Baptiste Leduc <baptiste.leduc@gmail.com>
 *
 * @template T of TypeIdentifier
 */
final class BuiltinType extends Type
{
    /**

ifier
    {
        return $this->typeIdentifier;
    }

    public function isIdentifiedBy(TypeIdentifier|string ...$identifiers): bool
    {
        foreach ($identifiers as $identifier) {
            if ($identifier === $this->typeIdentifier || $identif

     * @param T $typeIdentifier
     */
    public function __construct(
        private readonly TypeIdentifier $typeIdentifier,
    ) {
    }

    /**
     * @return T
     */
    public function getTypeIdentifier(): TypeIdent


php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\TypeInfo\Type;

use Symfony\Component\TypeInfo\Type;

/**
 * Represents a type composed of several other types.
 *
 * @author Mathias Arlaud <mathias.arlaud@gmail.com>
 *
 * @template T of Type
 */
interface CompositeTypeInterface
{
    /**
     *

>
     */
    public function getTypes(): array;

    /**
     * @param-immediately-invoked-callable $specification
     *
     * @param callable(Type): bool $specification
     */
    public function composedTypesAreSatisfiedBy(callable $specification): b


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Tests\Adapter;

use PHPUnit\Framework\Attributes\Group;
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\Cache\Adapter\RedisTagAwareAdapter;
use Symfony\Component\Cache\Traits\RedisProxy;

#[Group('integration')]
class RedisTagAwareAdapterTe

}

    public function createCachePool(int $defaultLifetime = 0, ?string $testMethod = null): CacheItemPoolInterface
    {
        if ('testClearWithPrefix' === $testMethod && \defined('Redis::SCAN_PREFIX')) {
            self::$redis->setOption(\Redis::OP

st extends RedisAdapterTest
{
    use TagAwareTestTrait;

    protected function setUp(): void
    {
        parent::setUp();
        $this->skippedTests['testTagItemExpiry'] = 'Testing expiration slows down the test suite';


buted with this source code.
 */

namespace Symfony\Component\Cache\Tests\Adapter;

use Psr\Cache\InvalidArgumentException;
use Symfony\Component\Cache\CacheItem;

/**
 * Common assertions for TagAware adapters.
 *
 * @method \Symfony\Component\Cache\Adapter\TagAwareAdapterInterface createCachePool(int $defaultLifetime = 0) Must be implemented by TestCase
 */
trait TagAwareTestTrait
{
    public function testInvalidTag()
    {
        $pool = $this->createCachePool();
        $item = $pool->getItem('foo');

    $i1 = $pool->getItem('i1');
        $i2 = $pool->getItem('i2');
        $i3 = $pool->getItem('i3');
        $foo = $pool->getItem('foo');

        $pool->save($i0->tag('bar'));
        $pool->save($i1->tag('foo'));
        $pool->save($i2->tag('foo')->

        $this->expectException(InvalidArgumentException::class);

        $item->tag(':');
    }

    public function testInvalidateTags()
    {
        $pool = $this->createCachePool();

        $i0 = $pool->getItem('i0');


buted with this source code.
 */

namespace Symfony\Component\Cache\Tests\DataCollector;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Cache\Adapter\NullAdapter;
use Symfony\Component\Cache\Adapter\TraceableAdapter;
use Symfony\Component\Cache\DataCollector\CacheDataCollector;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\VarDumper\Cloner\Data;

class CacheDataCollectorTest extends TestCase
{
    private const INSTANCE_NAME = 'tes

>assertSame(0, $statistics[self::INSTANCE_NAME]['reads'], 'reads');
        $this->assertSame(0, $statistics[self::INSTANCE_NAME]['hits'], 'hits');
        $this->assertSame(0, $statistics[self::INSTANCE_NAME]['misses'], 'misses');
        $this->assertSam

t';

    public function testEmptyDataCollector()
    {
        $statistics = $this->getCacheDataCollectorStatisticsFromEvents([]);

        $this->assertSame(0, $statistics[self::INSTANCE_NAME]['calls'], 'calls');
        $this-


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\TypeInfo\TypeResolver;

use PHPStan\PhpDocParser\Ast\PhpDoc\ParamTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\ReturnTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\VarTagValueNode;
use PHPStan\PhpDocParser\Lexer\Lexer;
use PHPStan\PhpDocParser\Parser\ConstExprParser;
use PHPStan\PhpDocParser\Parser\PhpDocParser;
use PHPStan\PhpDocParser\Pa

Info\TypeContext\TypeContext;
use Symfony\Component\TypeInfo\TypeContext\TypeContextFactory;

/**
 * Resolves type on reflection prioriziting PHP documentation.
 *
 * @author Mathias Arlaud <mathias.arlaud@gmail.com>
 */
final class PhpDocAwareReflectionTy

rser\TokenIterator;
use PHPStan\PhpDocParser\Parser\TypeParser;
use PHPStan\PhpDocParser\ParserConfig;
use Symfony\Component\TypeInfo\Exception\UnsupportedException;
use Symfony\Component\TypeInfo\Type;
use Symfony\Component\Type


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\TypeInfo\Type;

use Symfony\Component\TypeInfo\Exception\InvalidArgumentException;
use Symfony\Component\TypeInfo\Type;

/**
 * @author Mathias Arlaud <mathias.arlaud@gmail.com>
 * @author Baptiste Leduc <baptiste.leduc@gmail.com>
 *
 * @template T of ObjectType|GenericType<ObjectType>|Collection

   /**
     * @param list<T> $types
     */
    public function __construct(Type ...$types)
    {
        if (\count($types) < 2) {
            throw new InvalidArgumentException(\sprintf('"%s" expects at least 2 types.', self::class));
        }

Type<GenericType<ObjectType>>
 *
 * @implements CompositeTypeInterface<T>
 */
final class IntersectionType extends Type implements CompositeTypeInterface
{
    /**
     * @var list<T>
     */
    private readonly array $types;


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\TypeInfo\Type;

use Symfony\Component\TypeInfo\Type;
use Symfony\Component\TypeInfo\TypeIdentifier;

/**
 * Represents the exact shape of an anonymous object.
 *
 * The shape is stored sorted by key; two instances built from the same entries in
 * a different order compare equal through getShape() and produce the same string
 * representation. Ob

ok at the public, initialized
 * properties returned by get_object_vars(); non-public properties, uninitialized
 * typed properties and state exposed only through __get() or other magic
 * accessors are not visible.
 *
 * @author Benjamin Franzke <ben@bnf.

ject shapes are always sealed: unlike ArrayShapeType, no
 * extra-key/extra-value type is supported because the underlying
 * phpstan-phpdoc-parser AST node has no such notion.
 *
 * Presence and value checks in accepts() both lo


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\TypeInfo\Type;

use Symfony\Component\TypeInfo\Type;

/**
 * Represents a template placeholder, such as "T" in "Collection<T>".
 *
 * @author Mathias Arlaud <mathias.arlaud@gmail.com>
 * @author Baptiste Leduc <baptiste.leduc@gmail.com>
 *
 * @template T of

$name,
        private readonly Type $bound,
    ) {
    }

    public function getName(): string
    {
        return $this->name;
    }

    /**
     * @return T
     */
    public function getBound(): Type
    {
        return $this->bound;
    }

    p

Type
 *
 * @implements WrappingTypeInterface<T>
 */
final class TemplateType extends Type implements WrappingTypeInterface
{
    /**
     * @param T $bound
     */
    public function __construct(
        private readonly string


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\TypeInfo\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\TypeInfo\Type;
use Symfony\Component\TypeInfo\Type\CollectionType;
use Symfony\Component\TypeInfo\Type\UnionType;
use Symfony\Component\TypeInfo\TypeIdentifier;

class TypeTest extends TestCase
{
    public function testIsIdentifiedBy()
    {
        $this->assertTrue(Type::in

    $this->assertTrue(Type::collection(Type::object(\Iterator::class))->isIdentifiedBy(TypeIdentifier::OBJECT));
        $this->assertTrue(Type::generic(Type::object(\Iterator::class), Type::string())->isIdentifiedBy(TypeIdentifier::OBJECT));
        $this

tersection(Type::object(\Iterator::class), Type::object(\Stringable::class))->isIdentifiedBy(TypeIdentifier::OBJECT));
        $this->assertTrue(Type::union(Type::int(), Type::string())->isIdentifiedBy(TypeIdentifier::INT));


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\TypeInfo\Tests\TypeResolver;

use PHPUnit\Framework\TestCase;
use Symfony\Component\TypeInfo\Exception\UnsupportedException;
use Symfony\Component\TypeInfo\Tests\Fixtures\ReflectionExtractableDummy;
use Symfony\Component\TypeInfo\Tests\Fixtures\ReflectionExtractableDummyUsingTrait;
use Symfony\Component\TypeInfo\Tests\Fixtures\ReflectionExtractab

\ReflectionTypeResolver;

class ReflectionParameterTypeResolverTest extends TestCase
{
    private ReflectionParameterTypeResolver $resolver;

    protected function setUp(): void
    {
        $this->resolver = new ReflectionParameterTypeResolver(new Refl

leTrait;
use Symfony\Component\TypeInfo\Type;
use Symfony\Component\TypeInfo\TypeContext\TypeContextFactory;
use Symfony\Component\TypeInfo\TypeResolver\ReflectionParameterTypeResolver;
use Symfony\Component\TypeInfo\TypeResolver


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\TypeInfo\TypeResolver;

use Symfony\Component\TypeInfo\Exception\UnsupportedException;
use Symfony\Component\TypeInfo\Type;
use Symfony\Component\TypeInfo\TypeContext\TypeContext;
use Symfony\Component\TypeInfo\TypeContext\TypeContextFactory;

/**
 * Resolves type for a

c function __construct(
        private readonly ReflectionTypeResolver $reflectionTypeResolver,
        private readonly TypeContextFactory $typeContextFactory,
    ) {
    }

    public function resolve(mixed $subject, ?TypeContext $typeContext = null):

given parameter reflection.
 *
 * @author Mathias Arlaud <mathias.arlaud@gmail.com>
 * @author Baptiste Leduc <baptiste.leduc@gmail.com>
 */
final class ReflectionParameterTypeResolver implements TypeResolverInterface
{
    publi


se PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprFloatNode;
use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprIntegerNode;
use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprNullNode;
use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprStringNode;
use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprTrueNode;
use PHPStan\PhpDocParser\Ast\ConstExpr\ConstFetchNode;
use PHPStan\PhpDocParser\Ast\Type\ArrayShapeNode;
use PHPStan\PhpDocParser\Ast\Type\ArrayTypeNode;
use PHPStan\PhpDocParser\Ast\Type\CallableTypeNode;
use PHPStan

ype\NullableTypeNode;
use PHPStan\PhpDocParser\Ast\Type\ObjectShapeNode;
use PHPStan\PhpDocParser\Ast\Type\ThisTypeNode;
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
use PHPStan\PhpDocParser\Ast\Type\UnionTypeNode;
use PHPStan\PhpDocParser\Lexer\Lexer;
use

\PhpDocParser\Ast\Type\ConstTypeNode;
use PHPStan\PhpDocParser\Ast\Type\GenericTypeNode;
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
use PHPStan\PhpDocParser\Ast\Type\IntersectionTypeNode;
use PHPStan\PhpDocParser\Ast\T


ony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\TypeInfo\TypeResolver;

use Symfony\Component\TypeInfo\Exception\UnsupportedException;
use Symfony\Component\TypeInfo\Type;
use Symfony\Component\TypeInfo\TypeContext\TypeContext;

/**
 * Resolves type for a given subject.
 *
 * @author Mathias Arlaud <mathias.arlaud@gmail.com>
 * @author Baptiste Leduc <baptiste.leduc@gmail.com>
 */
inte

resolve a {@see Type} on a $subject.
     * If the resolver cannot resolve the type, it will throw a {@see UnsupportedException}.
     *
     * @throws UnsupportedException
     */
    public function resolve(mixed $subject, ?TypeContext $typeContext = nul

rface TypeResolverInterface
{
    /**
     * Try to


buted with this source code.
 */

namespace Symfony\Component\TypeInfo\Type;

use Symfony\Component\TypeInfo\Exception\InvalidArgumentException;
use Symfony\Component\TypeInfo\Type;
use Symfony\Component\TypeInfo\TypeIdentifier;

/**
 * Represents a key/value collection type.
 *
 * @author Mathias Arlaud <mathias.arlaud@gmail.com>
 * @author Baptiste Leduc <baptiste.leduc@gmail.com>
 *
 * @template T of BuiltinType<TypeIdentifier::ARRAY>|BuiltinType<TypeIdentifier::ITERABLE>|ObjectType|GenericType
 *
 * @im

ericType $type,
        private readonly bool $isList = false,
    ) {
        if ($type instanceof BuiltinType && TypeIdentifier::ARRAY !== $type->getTypeIdentifier() && TypeIdentifier::ITERABLE !== $type->getTypeIdentifier()) {
            throw new Inva

plements WrappingTypeInterface<T>
 */
class CollectionType extends Type implements WrappingTypeInterface
{
    /**
     * @param T $type
     */
    public function __construct(
        private readonly BuiltinType|ObjectType|Gen


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Tests\Adapter;

use PHPUnit\Framework\Attributes\Group;
use Symfony\Component\Cache\Adapter\AbstractAdapter;
use Symfony\Component\Cache\Adapter\RedisAdapter;
use Symfony\Component\Cache\Exception\InvalidArgumentException;

#[Group('integration')]
class RedisAdapterSentinelTest extends Abst

 if (!$hosts = getenv('REDIS_SENTINEL_HOSTS')) {
            self::markTestSkipped('REDIS_SENTINEL_HOSTS env var is not defined.');
        }
        if (!$service = getenv('REDIS_SENTINEL_SERVICE')) {
            self::markTestSkipped('REDIS_SENTINEL_SERV

ractRedisAdapterTestCase
{
    public static function setUpBeforeClass(): void
    {
        if (!class_exists(\RedisSentinel::class)) {
            self::markTestSkipped('The RedisSentinel class is required.');
        }


fo\Type\BuiltinType;
use Symfony\Component\TypeInfo\Type\CollectionType;
use Symfony\Component\TypeInfo\Type\EnumType;
use Symfony\Component\TypeInfo\Type\GenericType;
use Symfony\Component\TypeInfo\Type\IntersectionType;
use Symfony\Component\TypeInfo\Type\NullableType;
use Symfony\Component\TypeInfo\Type\ObjectShapeType;
use Symfony\Component\TypeInfo\Type\ObjectType;
use Symfony\Component\TypeInfo\Type\TemplateType;
use Symfony\Component\TypeInfo\Type\UnionType;

/**
 * Helper trait to create any type ea

   * @param T|U $identifier
     *
     * @return BuiltinType<T>
     */
    public static function builtin(TypeIdentifier|string $identifier): BuiltinType
    {
        /** @var T $identifier */
        $identifier = \is_string($identifier) ? TypeIdentifi

sily.
 *
 * @author Mathias Arlaud <mathias.arlaud@gmail.com>
 * @author Baptiste Leduc <baptiste.leduc@gmail.com>
 */
trait TypeFactoryTrait
{
    /**
     * @template T of TypeIdentifier
     * @template U value-of<T>
     *


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\TypeInfo\Type;

use Symfony\Component\TypeInfo\Exception\InvalidArgumentException;
use Symfony\Component\TypeInfo\Type;
use Symfony\Component\TypeInfo\TypeIdentifier;

/**
 * @author Mathias Arlaud <mathias.arlaud@gmail.com>
 *
 * @template T of Type
 *
 * @extends Union

nstruct(
        private readonly Type $type,
    ) {
        if ($type->isNullable()) {
            throw new InvalidArgumentException(\sprintf('Cannot create a "%s" with "%s" because it is already nullable.', self::class, $type));
        }

        if (

Type<T|BuiltinType<TypeIdentifier::NULL>>
 *
 * @implements WrappingTypeInterface<T>
 */
final class NullableType extends UnionType implements WrappingTypeInterface
{
    /**
     * @param T $type
     */
    public function __co


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\TypeInfo\Type;

use Symfony\Component\TypeInfo\Type;
use Symfony\Component\TypeInfo\TypeIdentifier;

/**
 * @author Mathias Arlaud <mathias.arlaud@gmail.com>
 * @author Baptiste Leduc <baptiste.leduc@gmail.com>
 *
 * @template T of class-string
 */
class ObjectType exten

ntifier::OBJECT;
    }

    /**
     * @return T
     */
    public function getClassName(): string
    {
        return $this->className;
    }

    public function isIdentifiedBy(TypeIdentifier|string ...$identifiers): bool
    {
        foreach ($identi

ds Type
{
    /**
     * @param T $className
     */
    public function __construct(
        private readonly string $className,
    ) {
    }

    public function getTypeIdentifier(): TypeIdentifier
    {
        return TypeIde


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\TypeInfo\Tests\TypeResolver;

use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Symfony\Component\TypeInfo\Tests\Fixtures\Dummy;
use Symfony\Component\TypeInfo\Tests\Fixtures\DummyWithPhpDoc;
use Symfony\Component\TypeInfo\Type;
use Symfony\Component\TypeInfo\Type

class PhpDocAwareReflectionTypeResolverTest extends TestCase
{
    #[DataProvider('readPhpDocDataProvider')]
    public function testReadPhpDoc(Type $expected, \Reflector $reflector)
    {
        $resolver = new PhpDocAwareReflectionTypeResolver(TypeReso

Context\TypeContextFactory;
use Symfony\Component\TypeInfo\TypeResolver\PhpDocAwareReflectionTypeResolver;
use Symfony\Component\TypeInfo\TypeResolver\StringTypeResolver;
use Symfony\Component\TypeInfo\TypeResolver\TypeResolver;


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\TypeInfo\Type;

use Symfony\Component\TypeInfo\Exception\InvalidArgumentException;
use Symfony\Component\TypeInfo\TypeIdentifier;

/**
 * @author Mathias Arlaud <mathias.arlaud@gmail.com>
 * @author Baptiste Leduc <baptiste.leduc@gmail.com>
 *
 * @template T

     * @param U $backingType
     */
    public function __construct(
        string $className,
        private readonly BuiltinType $backingType,
    ) {
        if (TypeIdentifier::INT !== $backingType->getTypeIdentifier() && TypeIdentifier::STRING !==

 of class-string<\BackedEnum>
 * @template U of BuiltinType<TypeIdentifier::INT>|BuiltinType<TypeIdentifier::STRING>
 *
 * @extends EnumType<T>
 */
final class BackedEnumType extends EnumType
{
    /**
     * @param T $className


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\TypeInfo;

/**
 * Identifier of a PHP native type.
 *
 * @author Mathias Arlaud <mathias.arlaud@gmail.com>
 * @author Baptiste Leduc <baptiste.leduc@gmail.com>
 */
enum TypeIdentifier: string
{
    case ARRAY = 'array';
    case BOOL = 'bool';
    case CALLA

ce';
    case STRING = 'string';
    case TRUE = 'true';
    case NEVER = 'never';
    case VOID = 'void';

    /**
     * @return list<string>
     */
    public static function values(): array
    {
        return array_column(self::cases(), 'value');

BLE = 'callable';
    case FALSE = 'false';
    case FLOAT = 'float';
    case INT = 'int';
    case ITERABLE = 'iterable';
    case MIXED = 'mixed';
    case NULL = 'null';
    case OBJECT = 'object';
    case RESOURCE = 'resour


 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\TypeInfo\Type;

use Symfony\Component\TypeInfo\Exception\InvalidArgumentException;
use Symfony\Component\TypeInfo\Type;
use Symfony\Component\TypeInfo\TypeIdentifier;

/**
 * @author Mathias Arlaud <mathias.arlaud@gmail.com>
 * @author Baptiste Leduc <baptiste.leduc@gmail.com>
 *
 * @template T of Type
 *
 * @implements CompositeTypeInterface<T>

pes)
    {
        if (\count($types) < 2) {
            throw new InvalidArgumentException(\sprintf('"%s" expects at least 2 types.', self::class));
        }

        foreach ($types as $type) {
            if ($type instanceof self) {
                th

 */
class UnionType extends Type implements CompositeTypeInterface
{
    /**
     * @var list<T>
     */
    private readonly array $types;

    /**
     * @param list<T> $types
     */
    public function __construct(Type ...$ty


function __construct(
        private readonly ReflectionTypeResolver $reflectionTypeResolver,
        private readonly TypeContextFactory $typeContextFactory,
    ) {
    }

    public function resolve(mixed $subject, ?TypeContext $typeContext = null): Ty

given property reflection.
 *
 * @author Mathias Arlaud <mathias.arlaud@gmail.com>
 * @author Baptiste Leduc <baptiste.leduc@gmail.com>
 */
final class ReflectionPropertyTypeResolver implements TypeResolverInterface
{
    public


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Cache\Tests\Adapter;

use PHPUnit\Framework\Attributes\Group;
use Relay\Relay;
use Relay\Sentinel;
use Symfony\Component\Cache\Adapter\AbstractAdapter;

#[Group('integration')]
class RelayAdapterSentinelTest extends AbstractRedisAdapterTestCase
{
    public

')) {
            self::markTestSkipped('REDIS_SENTINEL_HOSTS env var is not defined.');
        }
        if (!$service = getenv('REDIS_SENTINEL_SERVICE')) {
            self::markTestSkipped('REDIS_SENTINEL_SERVICE env var is not defined.');
        }

static function setUpBeforeClass(): void
    {
        if (!class_exists(Sentinel::class)) {
            self::markTestSkipped('The Relay\Sentinel class is required.');
        }
        if (!$hosts = getenv('REDIS_SENTINEL_HOSTS


ummyBackedEnum;
use Symfony\Component\TypeInfo\Tests\Fixtures\DummyEnum;
use Symfony\Component\TypeInfo\Type;
use Symfony\Component\TypeInfo\Type\ArrayShapeType;
use Symfony\Component\TypeInfo\Type\BackedEnumType;
use Symfony\Component\TypeInfo\Type\BuiltinType;
use Symfony\Component\TypeInfo\Type\CollectionType;
use Symfony\Component\TypeInfo\Type\EnumType;
use Symfony\Component\TypeInfo\Type\GenericType;
use Symfony\Component\TypeInfo\Type\IntersectionType;
use Symfony\Component\TypeInfo\Type\NullableType

o\TypeIdentifier;

class TypeFactoryTest extends TestCase
{
    public function testCreateBuiltin()
    {
        $this->assertEquals(new BuiltinType(TypeIdentifier::INT), Type::builtin(TypeIdentifier::INT));
        $this->assertEquals(new BuiltinType(Typ

;
use Symfony\Component\TypeInfo\Type\ObjectShapeType;
use Symfony\Component\TypeInfo\Type\ObjectType;
use Symfony\Component\TypeInfo\Type\TemplateType;
use Symfony\Component\TypeInfo\Type\UnionType;
use Symfony\Component\TypeInf


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\TypeInfo\Type;

use Symfony\Component\TypeInfo\Exception\InvalidArgumentException;
use Symfony\Component\TypeInfo\Type;
use Symfony\Component\TypeInfo\TypeIdentifier;

/**
 * Represents a generic type, which is a type that holds variable parts.
 *
 * @author Mathias Arlaud <mathias.arlaud@gmail.c

ype extends Type implements WrappingTypeInterface
{
    /**
     * @var list<Type>
     */
    private readonly array $variableTypes;

    /**
     * @param T $type
     */
    public function __construct(
        private readonly BuiltinType|ObjectType $t

om>
 * @author Baptiste Leduc <baptiste.leduc@gmail.com>
 *
 * @template T of BuiltinType<TypeIdentifier::ARRAY>|BuiltinType<TypeIdentifier::ITERABLE>|ObjectType
 *
 * @implements WrappingTypeInterface<T>
 */
final class GenericT


* This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\EventDispatcher\Tests\Fixtures;

use Symfony\Component\EventDispatcher\Attribute\AsEventListener;

#[AsEventListener(event: CustomEvent::class, method: 'onCustomEvent')]
#[AsEventListener(event: 'foo', priority: 42)]
#[AsEventListener(event: 'bar', method:

 public function onCustomEvent(CustomEvent $event): void
    {
    }

    public function onFoo(): void
    {
    }

    public function onBarEvent(): void
    {
    }

    #[AsEventListener(event: 'baz')]
    public function onBazEvent(): void
    {
    }

'onBarEvent')]
final class TaggedMultiListener
{


/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ExpressionLanguage\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\ExpressionLanguage\ExpressionFunction;

/**
 * Tests ExpressionFunction.
 *
 * @author Dany Maillard <danymaillard93b@gmail.com>
 */
class ExpressionFunctionTest extends T

xpressionFunction::fromPhp('fn_does_not_exist');
    }

    public function testFunctionNamespaced()
    {
        $this->expectException(\InvalidArgumentException::class);
        $this->expectExceptionMessage('An expression function name must be defined

estCase
{
    public function testFunctionDoesNotExist()
    {
        $this->expectException(\InvalidArgumentException::class);
        $this->expectExceptionMessage('PHP function "fn_does_not_exist" does not exist.');
        E


Symfony\Component\ExpressionLanguage\Tests\Fixtures\TestProvider;

class ExpressionLanguageTest extends TestCase
{
    public function testCachedParse()
    {
        $cacheMock = $this->createMock(CacheItemPoolInterface::class);
        $cacheItemMock = $this->createMock(CacheItemInterface::class);
        $savedParsedExpression = null;
        $expressionLanguage = new ExpressionLanguage($cacheMock);

        $cacheMock
            ->expects($this->exactly(2))
            ->method('getItem')
            -

$savedParsedExpression) {
                return $savedParsedExpression;
            })
        ;

        $cacheItemMock
            ->expects($this->exactly(1))
            ->method('set')
            ->with($this->isInstanceOf(ParsedExpression::class))

>with('1%20%2B%201%2F%2F')
            ->willReturn($cacheItemMock)
        ;

        $cacheItemMock
            ->expects($this->exactly(2))
            ->method('get')
            ->willReturnCallback(static function () use (&


buted with this source code.
 */

namespace Symfony\Component\ExpressionLanguage\Tests;

use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Symfony\Component\ExpressionLanguage\Lexer;
use Symfony\Component\ExpressionLanguage\SyntaxError;
use Symfony\Component\ExpressionLanguage\Token;
use Symfony\Component\ExpressionLanguage\TokenStream;

class LexerTest extends TestCase
{
    private Lexer $lexer;

    protected function setUp(): void
    {
        $this->lexer = new Lexer()

nStream($tokens, $expression), $this->lexer->tokenize($expression));
    }

    public function testTokenizeMultilineComment()
    {
        $expression = <<<EXPRESSION
            /**
             * This is 2^16, even if we could have
             * used

;
    }

    #[DataProvider('getTokenizeData')]
    public function testTokenize($tokens, $expression)
    {
        $tokens[] = new Token('end of expression', null, \strlen($expression) + 1);
        $this->assertEquals(new Toke


 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ExpressionLanguage\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Component\ExpressionLanguage\Node\ConstantNode;
use Symfony\Component\ExpressionLanguage\ParsedExpression;

class ParsedExpressionTest extends TestCase
{
    public function testSeriali

        $expression = new ParsedExpression('25', new ConstantNode('25'));

        $serializedExpression = serialize($expression);
        $unserializedExpression = unserialize($serializedExpression);

        $this->assertEquals($expression, $unserialize


);
        $lexer = new Lexer();
        $parser = new Parser([]);
        $parser->parse($lexer->tokenize('foo'));
    }

    public function testParseWithZeroInNames()
    {
        $this->expectException(SyntaxError::class);
        $this->expectExceptionMessage('Variable "foo" is not valid around position 1 for expression `foo`.');
        $lexer = new Lexer();
        $parser = new Parser([]);
        $parser->parse($lexer->tokenize('foo'), [0]);
    }

    public function testParsePrimaryExpressionWit

oes not exist around position 1 for expression `foo()`.');

        $parser->parse($stream);
    }

    public function testParseUnknownFunction()
    {
        $parser = new Parser([]);
        $tokenized = (new Lexer())->tokenize('foo()');

        $this

hUnknownFunctionThrows()
    {
        $parser = new Parser([]);
        $stream = (new Lexer())->tokenize('foo()');

        $this->expectException(SyntaxError::class);
        $this->expectExceptionMessage('The function "foo" d


n Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ExpressionLanguage\Tests\Fixtures;

use Symfony\Component\ExpressionLanguage\ExpressionFunction;
use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;

class TestProvider implements ExpressionFunctionProviderInterface
{
    public function getFunctions(): array
    {
        return [

=> $input, fn (array $values, $input) => $input),

            ExpressionFunction::fromPhp('strtoupper'),

            ExpressionFunction::fromPhp('\strtolower'),

            ExpressionFunction::fromPhp('Symfony\Component\ExpressionLanguage\Tests\Fixtures

new ExpressionFunction('identity', fn ($input)


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ExpressionLanguage\Tests\Node;

use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Symfony\Component\ExpressionLanguage\Compiler;

abstract class AbstractNodeTestCase extends TestCase
{
    #[DataProvider('getEvaluateData')]

;

    #[DataProvider('getCompileData')]
    public function testCompile($expected, $node, $functions = [])
    {
        $compiler = new Compiler($functions);
        $node->compile($compiler);
        $this->assertSame($expected, $compiler->getSource());

   public function testEvaluate($expected, $node, $variables = [], $functions = [])
    {
        $this->assertSame($expected, $node->evaluate($functions, $variables));
    }

    abstract public static function getEvaluateData()


 file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ExpressionLanguage\Tests\Node;

use Symfony\Component\ExpressionLanguage\Node\ArgumentsNode;
use Symfony\Component\ExpressionLanguage\Node\ArrayNode;

class ArgumentsNodeTest extends ArrayNodeTest
{
    public static function getCompileData(): array
    {

ode()],
        ];
    }

    public static function getDumpData(): \Generator
    {
        yield from [
            ['"a", "b"', static::getArrayNode()],
        ];
    }

    protected static function createArrayNode(): ArrayNode
    {
        return ne

 return [
            ['"a", "b"', static::getArrayN


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ExpressionLanguage\Tests\Node;

use Symfony\Component\ExpressionLanguage\Node\ArrayNode;
use Symfony\Component\ExpressionLanguage\Node\ConstantNode;

class ArrayNodeTest extends AbstractNodeTestCase
{
    public function testSerialization()
    {
        $node = $this->createArrayNode();

uals($this->createArrayNode(), $unserializedNode);
    }

    public static function getEvaluateData(): array
    {
        return [
            [['b' => 'a', 'b'], static::getArrayNode()],
        ];
    }

    public static function getCompileData(): arr

$node->addElement(new ConstantNode('foo'));

        $serializedNode = serialize($node);
        $unserializedNode = unserialize($serializedNode);

        $this->assertEquals($node, $unserializedNode);
        $this->assertNotEq


nent\ExpressionLanguage\Node\ArrayNode;
use Symfony\Component\ExpressionLanguage\Node\BinaryNode;
use Symfony\Component\ExpressionLanguage\Node\ConstantNode;
use Symfony\Component\ExpressionLanguage\Node\NameNode;
use Symfony\Component\ExpressionLanguage\SyntaxError;

class BinaryNodeTest extends AbstractNodeTestCase
{
    public static function getEvaluateData(): array
    {
        $array = new ArrayNode();
        $array->addElement(new ConstantNode('a'));
        $array->addElement(new ConstantNode('b')

naryNode('xor', new ConstantNode(true), new ConstantNode(true))],
            [false, new BinaryNode('and', new ConstantNode(true), new ConstantNode(false))],
            [false, new BinaryNode('&&', new ConstantNode(true), new ConstantNode(false))],

);

        return [
            [true, new BinaryNode('or', new ConstantNode(true), new ConstantNode(false))],
            [true, new BinaryNode('||', new ConstantNode(true), new ConstantNode(false))],
            [false, new Bi


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ExpressionLanguage\Tests\Node;

use Symfony\Component\ExpressionLanguage\Node\ConditionalNode;
use Symfony\Component\ExpressionLanguage\Node\ConstantNode;

class ConditionalNodeTest extends AbstractNodeTestCase
{
    public static function getEvaluateData():

ode(2))],
        ];
    }

    public static function getCompileData(): array
    {
        return [
            ['((true) ? (1) : (2))', new ConditionalNode(new ConstantNode(true), new ConstantNode(1), new ConstantNode(2))],
            ['((false) ? (1)

 array
    {
        return [
            [1, new ConditionalNode(new ConstantNode(true), new ConstantNode(1), new ConstantNode(2))],
            [2, new ConditionalNode(new ConstantNode(false), new ConstantNode(1), new ConstantN


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ExpressionLanguage\Tests\Node;

use Symfony\Component\ExpressionLanguage\Node\ConstantNode;

class ConstantNodeTest extends AbstractNodeTestCase
{
    public static function getEvaluateData(): array
    {
        return [
            [false, new ConstantNode(false)],
            [true, new Consta

de([1, 'b' => 'a'])],
        ];
    }

    public static function getCompileData(): array
    {
        return [
            // Booleans
            ['false', new ConstantNode(false)],
            ['true', new ConstantNode(true)],

            // Null

ntNode(true)],
            [null, new ConstantNode(null)],
            [3, new ConstantNode(3)],
            [3.3, new ConstantNode(3.3)],
            ['foo', new ConstantNode('foo')],
            [[1, 'b' => 'a'], new ConstantNo


 This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ExpressionLanguage\Tests\Node;

use Symfony\Component\ExpressionLanguage\Node\ConstantNode;
use Symfony\Component\ExpressionLanguage\Node\FunctionNode;
use Symfony\Component\ExpressionLanguage\Node\Node;

class FunctionNodeTest extends AbstractNodeTestCase
{

atic function getCompileData(): array
    {
        return [
            ['foo("bar")', new FunctionNode('foo', new Node([new ConstantNode('bar')])), ['foo' => static::getCallables()]],
        ];
    }

    public static function getDumpData(): array

    public static function getEvaluateData(): array
    {
        return [
            ['bar', new FunctionNode('foo', new Node([new ConstantNode('bar')])), [], ['foo' => static::getCallables()]],
        ];
    }

    public st


buted with this source code.
 */

namespace Symfony\Component\ExpressionLanguage\Tests\Node;

use Symfony\Component\ExpressionLanguage\Node\ArgumentsNode;
use Symfony\Component\ExpressionLanguage\Node\ArrayNode;
use Symfony\Component\ExpressionLanguage\Node\ConstantNode;
use Symfony\Component\ExpressionLanguage\Node\GetAttrNode;
use Symfony\Component\ExpressionLanguage\Node\NameNode;

class GetAttrNodeTest extends AbstractNodeTestCase
{
    public static function getEvaluateData(): array
    {
        retur

e('b'), self::getArrayNode(), GetAttrNode::ARRAY_CALL), ['foo' => ['b' => 'a', 'b']]],

            ['bar', new GetAttrNode(new NameNode('foo'), new ConstantNode('foo'), self::getArrayNode(), GetAttrNode::PROPERTY_CALL), ['foo' => new Obj()]],

n [
            ['b', new GetAttrNode(new NameNode('foo'), new ConstantNode(0), self::getArrayNode(), GetAttrNode::ARRAY_CALL), ['foo' => ['b' => 'a', 'b']]],
            ['a', new GetAttrNode(new NameNode('foo'), new ConstantNod


/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ExpressionLanguage\Tests\Node;

use Symfony\Component\ExpressionLanguage\Node\NameNode;

class NameNodeTest extends AbstractNodeTestCase
{
    public static function getEvaluateData(): array
    {
        return [
            ['bar', new NameNode('foo

static function getCompileData(): array
    {
        return [
            ['$foo', new NameNode('foo')],
        ];
    }

    public static function getDumpData(): array
    {
        return [
            ['foo', new NameNode('foo')],
        ];
    }
}


 part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ExpressionLanguage\Tests\Node;

use PHPUnit\Framework\TestCase;
use Symfony\Component\ExpressionLanguage\Compiler;
use Symfony\Component\ExpressionLanguage\Node\ConstantNode;
use Symfony\Component\ExpressionLanguage\Node\Node;

class NodeTest extends TestCase
{
    publi

tring) $node
        );
    }

    public function testSerialization()
    {
        $node = new Node(['foo' => 'bar'], ['bar' => 'foo']);

        $serializedNode = serialize($node);
        $unserializedNode = unserialize($serializedNode);

        $this

c function testToString()
    {
        $node = new Node([new ConstantNode('foo')]);

        $this->assertEquals(<<<'EOF'
            Node(
                ConstantNode(value: 'foo')
            )
            EOF,
            (s


he Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ExpressionLanguage\Tests\Node;

use Symfony\Component\ExpressionLanguage\Node\NullCoalescedNameNode;

class NullCoalescedNameNodeTest extends AbstractNodeTestCase
{
    public static function getEvaluateData(): array
    {
        return [
            [null, new NullCoalescedNameN

 function getCompileData(): array
    {
        return [
            ['$foo ?? null', new NullCoalescedNameNode('foo')],
        ];
    }

    public static function getDumpData(): array
    {
        return [
            ['foo ?? null', new NullCoalescedN

ode('foo'), []],
        ];
    }

    public static


buted with this source code.
 */

namespace Symfony\Component\ExpressionLanguage\Node;

use Symfony\Component\ExpressionLanguage\Compiler;
use Symfony\Component\ExpressionLanguage\SyntaxError;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 *
 * @internal
 */
class BinaryNode extends Node
{
    private const OPERATORS = [
        '~' => '.',
        'and' => '&&',
        'or' => '||',
    ];

    private const FUNCTIONS = [
        '**' => 'pow',
        '..' => 'range',
        'in' => '\\in_array'

Node $right)
    {
        parent::__construct(
            ['left' => $left, 'right' => $right],
            ['operator' => $operator]
        );
    }

    public function compile(Compiler $compiler): void
    {
        $operator = $this->attributes['ope

,
        'not in' => '!\\in_array',
        'contains' => 'str_contains',
        'starts with' => 'str_starts_with',
        'ends with' => 'str_ends_with',
    ];

    public function __construct(string $operator, Node $left,


ge.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ExpressionLanguage\Node;

use Symfony\Component\ExpressionLanguage\Compiler;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 *
 * @internal
 */
class ConstantNode extends Node
{
    public function __construct(
        mixed $value,
        private bool $isIdentifier = false,
        publi

->attributes['value']);
    }

    public function evaluate(array $functions, array $values): mixed
    {
        return $this->attributes['value'];
    }

    public function toArray(): array
    {
        $array = [];
        $value = $this->attributes['

c readonly bool $isNullSafe = false,
    ) {
        parent::__construct(
            [],
            ['value' => $value]
        );
    }

    public function compile(Compiler $compiler): void
    {
        $compiler->repr($this


buted with this source code.
 */

namespace Symfony\Component\ExpressionLanguage\Node;

use Symfony\Component\ExpressionLanguage\Compiler;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 *
 * @internal
 */
class GetAttrNode extends Node
{
    public const PROPERTY_CALL = 1;
    public const METHOD_CALL = 2;
    public const ARRAY_CALL = 3;

    /**
     * @param self::* $type
     * @param bool    $isNullSafe Whether the access uses the `?.[]` null-safe operator; only honored for self::ARRAY_CALL.

pe, bool $isNullSafe = false)
    {
        $isNullSafe = self::ARRAY_CALL === $type && $isNullSafe;

        parent::__construct(
            ['node' => $node, 'attribute' => $attribute, 'arguments' => $arguments],
            ['type' => $type, 'is_null_c

   *                            For self::PROPERTY_CALL and self::METHOD_CALL, null-safety is driven by ConstantNode::$isNullSafe.
     */
    public function __construct(Node $node, Node $attribute, ArrayNode $arguments, int $ty


ony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ExpressionLanguage\Node;

use Symfony\Component\ExpressionLanguage\Compiler;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 *
 * @internal
 */
class NameNode extends Node
{
    public function __construct(string $name)
    {
        parent::__construct(
            [],
            ['name' => $name]
        );
    }

    public fun

  $compiler->raw('$'.$this->attributes['name']);
    }

    public function evaluate(array $functions, array $values): mixed
    {
        return $values[$this->attributes['name']];
    }

    public function toArray(): array
    {
        return [$this->a

ction compile(Compiler $compiler): void
    {