<?xml version="1.0"?>
<psalm
    errorLevel="2"
    phpVersion="8.2"
    findUnusedBaselineEntry="false"
    findUnusedCode="false"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="https://getpsalm.org/schema/config"
    xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
>
    <projectFiles>
        <directory name="src" />
        <directory name="static-analysis" />
        <directory name="tests" />
        <ignoreFiles>
            <directory name="vendor" />
        </ignoreFiles>
    </projectFiles>
    <stubs>
        <file name="vendor/jetbrains/phpstorm-stubs/PDO/PDO.php" />
        <file name="vendor/jetbrains/phpstorm-stubs/ibm_db2/ibm_db2.php" />
        <file name="vendor/jetbrains/phpstorm-stubs/mysqli/mysqli.php" />
        <file name="vendor/jetbrains/phpstorm-stubs/oci8/oci8.php" />
        <file name="vendor/jetbrains/phpstorm-stubs/sqlsrv/sqlsrv.php" />
    </stubs>
    <issueHandlers>
        <ArgumentTypeCoercion>
            <!--
                The actual return type of the driver functions or methods depends on the
                values of the passed arguments, so it cannot be determined statically.
            -->
            <errorLevel type="suppress">
                <file name="src/Driver/PgSQL/Result.php"/>
            </errorLevel>
        </ArgumentTypeCoercion>
        <ConflictingReferenceConstraint>
            <errorLevel type="suppress">
                <!--
                    This one is just too convoluted for Psalm to figure out, by
                    its author's own admission
                -->
                <file name="src/Driver/OCI8/ConvertPositionalToNamedPlaceholders.php"/>
            </errorLevel>
        </ConflictingReferenceConstraint>
        <DeprecatedClass>
            <errorLevel type="suppress">
                <!--
                    See https://github.com/doctrine/dbal/pull/6343
                    TODO: remove in 5.0.0
                -->
                <referencedClass name="Doctrine\DBAL\Platforms\Keywords\MySQL80Keywords" />
                <referencedClass name="Doctrine\DBAL\Platforms\MariaDB1052Platform" />
                <referencedClass name="Doctrine\DBAL\Platforms\MySQL80Platform" />
                <referencedClass name="Doctrine\DBAL\Platforms\PostgreSQL120Platform" />
            </errorLevel>
        </DeprecatedClass>
        <DeprecatedMethod>
            <errorLevel type="suppress">
                <!--
                    See https://github.com/doctrine/dbal/pull/6202
                    TODO: remove in 4.0.0
                -->
                <referencedMethod name="Doctrine\DBAL\Schema\TableDiff::getModifiedColumns" />
                <referencedMethod name="Doctrine\DBAL\Schema\TableDiff::getRenamedColumns" />
                <referencedMethod name="Doctrine\DBAL\Platforms\AbstractMySQLPlatform::getColumnTypeSQLSnippets" />
                <referencedMethod name="Doctrine\DBAL\Platforms\AbstractMySQLPlatform::getDatabaseNameSQL" />

                <!-- TODO for PHPUnit 11 -->
                <referencedMethod name="PHPUnit\Framework\TestCase::iniSet"/>
            </errorLevel>
        </DeprecatedMethod>
        <DocblockTypeContradiction>
            <errorLevel type="suppress">
                <!--
                    These issues can be mostly divided in the following categories:
                      1. Union types not supported at the language level (require dropping PHP 7 support)
                      2. Associative arrays with typed elements used instead of classes (require breaking API changes)
                -->
                <file name="src/Connection.php"/>
                <file name="src/Driver/IBMDB2/Statement.php"/>
                <directory name="src/Driver/PgSQL"/>
                <!--
                    Requires a release of https://github.com/JetBrains/phpstorm-stubs/pull/1255
                -->
                <file name="src/Driver/PDO/Connection.php"/>
                <file name="src/DriverManager.php"/>
                <file name="src/Platforms/AbstractMySQLPlatform.php"/>
                <file name="src/Platforms/AbstractPlatform.php"/>
                <file name="src/Platforms/SQLServerPlatform.php"/>
                <file name="src/Platforms/SQLitePlatform.php"/>
                <file name="src/Schema/Column.php"/>
                <!-- See https://github.com/vimeo/psalm/issues/5472 -->
                <file name="src/Portability/Converter.php"/>
                <!-- We're checking for invalid input -->
                <file name="src/Configuration.php"/>
            </errorLevel>
        </DocblockTypeContradiction>
        <FalsableReturnStatement>
            <errorLevel type="suppress">
                <!--
                    Fixing these issues requires an API change
                -->
                <file name="src/Driver/PDO/SQLSrv/Connection.php"/>
                <file name="src/Driver/SQLSrv/Connection.php"/>
            </errorLevel>
        </FalsableReturnStatement>
        <ImpureMethodCall>
            <errorLevel type="suppress">
                <!--
                    Requires a release of
                    https://github.com/vimeo/psalm/pull/3171
                -->
                <file name="src/Exception/DriverException.php"/>
            </errorLevel>
        </ImpureMethodCall>
        <ImplementedReturnTypeMismatch>
            <errorLevel type="suppress">
                <!-- Fixing this issue requires an API change -->
                <file name="src/Driver/OCI8/Connection.php"/>
            </errorLevel>
        </ImplementedReturnTypeMismatch>
        <InaccessibleProperty>
            <errorLevel type="suppress">
                <!--
                     Even though DateInterval properties are recommended to be considered as readonly,
                     there is no way to initialize an inverted interval using the constructor.

                     See: https://github.com/vimeo/psalm/pull/9895
                -->
                <file name="src/Types/DateIntervalType.php"/>
                <file name="tests/Types/DateIntervalTest.php"/>
            </errorLevel>
        </InaccessibleProperty>
        <InvalidArgument>
            <errorLevel type="suppress">
                <!-- We're testing with invalid input here. -->
                <file name="tests/Driver/PDO/*/DriverTest.php"/>
                <file name="tests/Functional/Driver/Mysqli/ConnectionTest.php"/>
                <file name="tests/Platforms/AbstractPlatformTestCase.php"/>
            </errorLevel>
        </InvalidArgument>
        <InvalidArrayOffset>
            <errorLevel type="suppress">
                <!-- https://github.com/vimeo/psalm/issues/10213 -->
                <file name="tests/Functional/BinaryDataAccessTest.php"/>
            </errorLevel>
        </InvalidArrayOffset>
        <InvalidDocblock>
            <errorLevel type="suppress">
                <!-- See https://github.com/vimeo/psalm/issues/5472 -->
                <file name="src/Portability/Converter.php"/>
            </errorLevel>
        </InvalidDocblock>
        <InvalidPropertyAssignmentValue>
            <errorLevel type="suppress">
                <!-- Fixing this issue requires an API change -->
                <file name="src/Driver/PDO/Exception.php"/>
            </errorLevel>
        </InvalidPropertyAssignmentValue>
        <LessSpecificReturnStatement>
            <!--
                The actual return type of the driver functions or methods depends on the
                values of the passed arguments, so it cannot be determined statically.
            -->
            <errorLevel type="suppress">
                <file name="src/Driver/IBMDB2/Result.php"/>
                <file name="src/Driver/OCI8/Result.php"/>
                <file name="src/Driver/PDO/Result.php"/>
                <file name="src/Driver/PgSQL/Result.php"/>
                <file name="src/Driver/SQLite3/Result.php"/>
            </errorLevel>
        </LessSpecificReturnStatement>
        <MoreSpecificReturnType>
            <errorLevel type="suppress">
                <!--
                    The actual return type of the driver functions or methods depends on the
                    values of the passed arguments, so it cannot be determined statically.
                -->
                <file name="src/Driver/IBMDB2/Result.php"/>
                <file name="src/Driver/OCI8/Result.php"/>
                <file name="src/Driver/PDO/Result.php"/>
                <file name="src/Driver/PgSQL/Result.php"/>
                <file name="src/Driver/SQLite3/Result.php"/>
            </errorLevel>
        </MoreSpecificReturnType>
        <NoValue>
            <errorLevel type="suppress">
                <!--
                    This error looks bogus.
                -->
                <file name="static-analysis/driver-manager-retrieves-correct-connection-type.php"/>
            </errorLevel>
        </NoValue>
        <NullableReturnStatement>
            <errorLevel type="suppress">
                <!--
                    Fixing this issue requires an API change
                -->
                <file name="src/Driver/AbstractSQLiteDriver.php"/>
            </errorLevel>
        </NullableReturnStatement>
        <PossiblyInvalidArrayOffset>
            <errorLevel type="suppress">
                <!-- $array[key($array)] is safe. -->
                <file name="src/Query/QueryBuilder.php"/>
            </errorLevel>
        </PossiblyInvalidArrayOffset>
        <PossiblyNullArgument>
            <errorLevel type="suppress">
                <!--
                    This is a valid issue and requires some refactoring.
                -->
                <file name="src/Schema/SQLiteSchemaManager.php"/>
            </errorLevel>
        </PossiblyNullArgument>
        <PossiblyUndefinedArrayOffset>
            <errorLevel type="suppress">
                <!-- See https://github.com/psalm/psalm-plugin-phpunit/pull/82 -->
                <file name="tests/Functional/PrimaryReadReplicaConnectionTest.php"/>
                <file name="tests/Functional/Schema/PostgreSQLSchemaManagerTest.php"/>
                <!-- There is no way to mark a nullable element in an array shape as always set,
                     and the PHPUnit plugin for Psalm does not seem to understand static assertions -->
                <file name="tests/TestUtil.php"/>
            </errorLevel>
        </PossiblyUndefinedArrayOffset>
        <PossiblyUndefinedVariable>
            <errorLevel type="suppress">
                <!--
                    See https://github.com/vimeo/psalm/issues/4354
                -->
                <file name="src/Schema/AbstractSchemaManager.php"/>
            </errorLevel>
        </PossiblyUndefinedVariable>
        <PossiblyFalseReference>
            <errorLevel type="suppress">
                <!--
                    oci_new_descriptor() returns OCI-Lob|false on PHP 7 and OCILob|null on PHP 8
                -->
                <file name="src/Driver/OCI8/Statement.php"/>
            </errorLevel>
        </PossiblyFalseReference>
        <PropertyNotSetInConstructor>
            <errorLevel type="suppress">
                <!-- See https://github.com/psalm/psalm-plugin-phpunit/issues/107 -->
                <!-- See https://github.com/sebastianbergmann/phpunit/pull/4610 -->
                <directory name="tests"/>
            </errorLevel>
        </PropertyNotSetInConstructor>
        <RedundantConditionGivenDocblockType>
            <errorLevel type="suppress">
                <!--
                    Fixing these issues requires support of union types at the language level
                    or breaking API changes.
                -->
                <file name="src/Platforms/AbstractMySQLPlatform.php"/>
                <file name="tests/Functional/Driver/AbstractDriverTestCase.php"/>

                <!-- We're checking for invalid input. -->
                <directory name="src/Driver/PgSQL"/>
                <file name="src/Result.php"/>

                <!-- We're testing invalid input. -->
                <file name="tests/Types/DateImmutableTypeTest.php"/>
                <file name="tests/Types/DateTimeImmutableTypeTest.php"/>
                <file name="tests/Types/TimeImmutableTypeTest.php"/>

                <!-- False positive: "mixed is never string" -->
                <file name="src/Platforms/PostgreSQLPlatform.php" />
            </errorLevel>
        </RedundantConditionGivenDocblockType>
        <RedundantPropertyInitializationCheck>
            <errorLevel type="suppress">
                <!-- Running isset() checks on properties that should be initialized by setUp() is fine. -->
                <directory name="tests"/>

                <!-- Ignore isset() checks in destructors. -->
                <file name="src/Driver/PgSQL/Connection.php"/>
                <file name="src/Driver/PgSQL/Statement.php"/>
            </errorLevel>
        </RedundantPropertyInitializationCheck>
        <TypeDoesNotContainNull>
            <errorLevel type="suppress">
                <!-- See https://github.com/psalm/psalm-plugin-phpunit/issues/107 -->
                <file name="tests/Functional/Schema/SchemaManagerFunctionalTestCase.php"/>
            </errorLevel>
        </TypeDoesNotContainNull>
        <TypeDoesNotContainType>
            <errorLevel type="suppress">
                <!-- See https://github.com/vimeo/psalm/issues/11008 -->
                <file name="src/Driver/SQLite3/Result.php"/>
                <!-- Ignore isset() checks in destructors. -->
                <file name="src/Driver/PgSQL/Connection.php"/>
                <file name="src/Driver/PgSQL/Statement.php"/>
            </errorLevel>
        </TypeDoesNotContainType>
        <UndefinedClass>
            <errorLevel type="suppress">
                <!-- New PDO classes introduced in PHP 8.4 -->
                <referencedClass name="Pdo\Mysql"/>
                <referencedClass name="Pdo\Pgsql"/>
                <referencedClass name="Pdo\Sqlite"/>
            </errorLevel>
        </UndefinedClass>
        <UndefinedDocblockClass>
            <errorLevel type="suppress">
                <!-- See https://github.com/vimeo/psalm/issues/5472 -->
                <referencedClass name="Doctrine\DBAL\Portability\T"/>
                <!--
                    The OCI-Lob class was renamed to OCILob in PHP 8 while Psalm infers PHP 7 from composer.json
                    and may not properly interpret the LanguageLevelTypeAware annotation from the stubs.
                -->
                <referencedClass name="OCILob"/>
            </errorLevel>
        </UndefinedDocblockClass>
        <UndefinedMethod>
            <errorLevel type="suppress">
                <!-- New PDO static constructor introduced in PHP 8.4 -->
                <referencedMethod name="PDO::connect"/>
            </errorLevel>
        </UndefinedMethod>
        <UnsupportedPropertyReferenceUsage>
            <errorLevel type="suppress">
                <!-- This code is valid -->
                <file name="src/Driver/Mysqli/Result.php"/>
                <file name="src/Driver/Mysqli/Statement.php"/>
            </errorLevel>
        </UnsupportedPropertyReferenceUsage>
        <UnsupportedReferenceUsage>
            <errorLevel type="suppress">
                <!-- This code is valid -->
                <file name="src/Driver/SQLSrv/Statement.php"/>
            </errorLevel>
        </UnsupportedReferenceUsage>
        <InvalidReturnStatement>
            <errorLevel type="suppress">
                <!-- lastInsertId has a return type that does not match the one defined in the interface-->
                <file name="src/Driver/Mysqli/Connection.php"/>

                <!-- See https://github.com/vimeo/psalm/issues/5472 -->
                <file name="src/Portability/Converter.php"/>
            </errorLevel>
        </InvalidReturnStatement>
        <InvalidReturnType>
            <errorLevel type="suppress">
                <!-- lastInsertId has a return type that does not match the one defined in the interface-->
                <file name="src/Driver/Mysqli/Connection.php"/>

                <!-- See https://github.com/vimeo/psalm/issues/5472 -->
                <file name="src/Portability/Converter.php"/>
            </errorLevel>
        </InvalidReturnType>
        <InvalidScalarArgument>
            <errorLevel type="suppress">
                <!-- See https://github.com/vimeo/psalm/issues/4295 -->
                <file name="src/Exception/DriverException.php"/>

                <!-- See https://bugs.php.net/bug.php?id=77591 -->
                <referencedFunction name="db2_autocommit"/>

                <!-- We're testing invalid input. -->
                <file name="tests/Functional/Driver/Mysqli/ConnectionTest.php"/>
            </errorLevel>
        </InvalidScalarArgument>
    </issueHandlers>
</psalm>
