Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Drop Psalm in favor of PHPStan #1852

Merged
merged 1 commit into from
Jan 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
.gitignore export-ignore
phpunit.xml.dist export-ignore
phpcs.xml.dist export-ignore
psalm.xml.dist export-ignore
phpstan-baseline.neon export-ignore
phpstan.neon.dist export-ignore
/docs export-ignore
/tests export-ignore
.symfony.bundle.yaml export-ignore
25 changes: 3 additions & 22 deletions .github/workflows/static-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,6 @@ on:
- "*.x"

jobs:
static-analysis-psalm:
name: "Static Analysis with Psalm"
runs-on: "ubuntu-latest"

steps:
- name: "Checkout code"
uses: "actions/checkout@v4"

- name: "Install PHP"
uses: "shivammathur/setup-php@v2"
with:
coverage: "none"
php-version: "8.2"

- name: "Enforce using stable dependencies"
run: "composer config minimum-stability stable"

- name: "Install dependencies with Composer"
uses: "ramsey/composer-install@v3"

- name: "Run a static analysis with vimeo/psalm"
run: "vendor/bin/psalm --show-info=false --stats --output-format=github --find-unused-psalm-suppress"
static-analysis:
name: "Static Analysis"
uses: "doctrine/.github/.github/workflows/[email protected]"
8 changes: 4 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,10 @@
"doctrine/deprecations": "^1.0",
"doctrine/orm": "^2.17 || ^3.0",
"friendsofphp/proxy-manager-lts": "^1.0",
"phpstan/phpstan": "2.1.1",
"phpstan/phpstan-phpunit": "2.0.3",
"phpstan/phpstan-strict-rules": "^2",
"phpunit/phpunit": "^9.5.26",
"psalm/plugin-phpunit": "^0.18.4",
"psalm/plugin-symfony": "^5",
"psr/log": "^1.1.4 || ^2.0 || ^3.0",
"symfony/phpunit-bridge": "^6.1 || ^7.0",
"symfony/property-info": "^5.4 || ^6.0 || ^7.0",
Expand All @@ -65,8 +66,7 @@
"symfony/var-exporter": "^5.4 || ^6.2 || ^7.0",
"symfony/web-profiler-bundle": "^5.4 || ^6.0 || ^7.0",
"symfony/yaml": "^5.4 || ^6.0 || ^7.0",
"twig/twig": "^1.34 || ^2.12 || ^3.0",
"vimeo/psalm": "^5.15"
"twig/twig": "^1.34 || ^2.12 || ^3.0"
},
"conflict": {
"doctrine/annotations": ">=3.0",
Expand Down
9 changes: 9 additions & 0 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
parameters:
level: 1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is way too low compared to on what level Psalm ran.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah :( I will try to increase it slowly. Psalm was running on high level because of carefully crafted suppression rules, somebody has to put in the work to make them for phpstan. I've already run into phpstan/phpstan#12414 (this is the kind of things baselines hide)

I'll make it to lvl2 today. Let me know if you would be interested in help to update it to some other lvl.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll have a look, but I won't be able to start right away. A temporary baseline would've been good in order to not lose coverage and track the progress.

paths:
- src
- tests

excludePaths:
- src/Command/Proxy/ConvertMappingDoctrineCommand.php
- src/Command/Proxy/EnsureProductionSettingsDoctrineCommand.php
Comment on lines +8 to +9
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apparently, the errors in these 2 files cannot be baselined

66 changes: 0 additions & 66 deletions psalm.xml.dist

This file was deleted.

1 change: 1 addition & 0 deletions src/Command/CreateDatabaseDoctrineCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int

// Need to get rid of _every_ occurrence of dbname from connection configuration as we have already extracted all relevant info from url
/** @psalm-suppress InvalidArrayOffset Need to be compatible with DBAL < 4, which still has `$params['url']` */
/** @phpstan-ignore unset.offset */
unset($params['dbname'], $params['path'], $params['url']);

if ($connection->getDatabasePlatform() instanceof PostgreSQLPlatform) {
Expand Down
1 change: 1 addition & 0 deletions src/Command/DoctrineCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public function __construct(ManagerRegistry $doctrine)
*/
protected function getEntityGenerator()
{
/** @phpstan-ignore class.notFound */
$entityGenerator = new EntityGenerator();
$entityGenerator->setGenerateAnnotations(false);
$entityGenerator->setGenerateStubMethods(true);
Expand Down
1 change: 1 addition & 0 deletions src/Command/DropDatabaseDoctrineCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
}

/** @psalm-suppress InvalidArrayOffset Need to be compatible with DBAL < 4, which still has `$params['url']` */
/* @phpstan-ignore unset.offset */
unset($params['dbname'], $params['url']);

if ($connection->getDatabasePlatform() instanceof PostgreSQLPlatform) {
Expand Down
2 changes: 2 additions & 0 deletions src/Command/ImportMappingDoctrineCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
}
}

/* @phpstan-ignore class.notFound */
$cme = new ClassMetadataExporter();
$exporter = $cme->getExporter($type);
$exporter->setOverwriteExistingFiles($input->getOption('force'));
Expand All @@ -126,6 +127,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$emName = $input->getOption('em');
$emName = $emName ? $emName : 'default';

/* @phpstan-ignore class.notFound */
$cmf = new DisconnectedClassMetadataFactory();
$cmf->setEntityManager($em);
$metadata = $cmf->getAllMetadata();
Expand Down
2 changes: 2 additions & 0 deletions src/Command/Proxy/DoctrineCommandHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,14 @@ public static function setApplicationEntityManager(Application $application, $em
assert($em instanceof EntityManagerInterface);
$helperSet = $application->getHelperSet();
/** @psalm-suppress InvalidArgument ORM < 3 specific */
/* @phpstan-ignore class.notFound */
$helperSet->set(new EntityManagerHelper($em), 'em');

trigger_deprecation(
'doctrine/doctrine-bundle',
'2.7',
'Providing an EntityManager using "%s" is deprecated. Use an instance of "%s" instead.',
/* @phpstan-ignore class.notFound */
EntityManagerHelper::class,
EntityManagerProvider::class,
);
Expand Down
10 changes: 6 additions & 4 deletions src/ConnectionFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

use const PHP_EOL;

/** @psalm-import-type Params from DriverManager */
/** @phpstan-import-type Params from DriverManager */
class ConnectionFactory
{
/** @internal */
Expand Down Expand Up @@ -63,7 +63,7 @@ public function __construct(array $typesConfig, ?DsnParser $dsnParser = null)
*
* @param mixed[] $params
* @param array<string, string> $mappingTypes
* @psalm-param Params $params
* @phpstan-param Params $params
*
* @return Connection
*/
Expand Down Expand Up @@ -108,6 +108,7 @@ public function createConnection(array $params, ?Configuration $config = null, ?
throw InvalidWrapperClass::new($params['wrapperClass']);
}

/* @phpstan-ignore staticMethod.notFound */
throw DBALException::invalidWrapperClass($params['wrapperClass']);
}

Expand Down Expand Up @@ -186,6 +187,7 @@ private function getDatabasePlatform(Connection $connection): AbstractPlatform
} catch (DriverException $driverException) {
$class = class_exists(DBALException::class) ? DBALException::class : ConnectionException::class;

/* @phpstan-ignore new.interface */
throw new $class(
'An exception occurred while establishing a connection to figure out your platform version.' . PHP_EOL .
"You can circumvent this by setting a 'server_version' configuration value" . PHP_EOL . PHP_EOL .
Expand Down Expand Up @@ -244,11 +246,11 @@ private function addDatabaseSuffix(array $params): array
* updated list of parameters.
*
* @param mixed[] $params The list of parameters.
* @psalm-param Params $params
* @phpstan-param Params $params
*
* @return mixed[] A modified list of parameters with info from a database
* URL extracted into individual parameter parts.
* @psalm-return Params
* @phpstan-return Params
*
* @throws DBALException
*/
Expand Down
10 changes: 5 additions & 5 deletions src/DataCollector/DoctrineDataCollector.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@
use function usort;

/**
* @psalm-type QueryType = array{
* @phpstan-type QueryType = array{
* executionMS: float,
* explainable: bool,
* sql: string,
* params: ?array<array-key, mixed>,
* runnable: bool,
* types: ?array<array-key, Type|int|string|null>,
* }
* @psalm-type DataType = array{
* @phpstan-type DataType = array{
* caches: array{
* enabled: bool,
* counts: array<"puts"|"hits"|"misses", int>,
Expand All @@ -54,7 +54,7 @@ class DoctrineDataCollector extends BaseCollector

/**
* @var mixed[][]|null
* @psalm-var ?array<string, list<QueryType&array{count: int, index: int, executionPercent?: float}>>
* @phpstan-var ?array<string, list<QueryType&array{count: int, index: int, executionPercent?: float}>>
*/
private ?array $groupedQueries = null;

Expand Down Expand Up @@ -216,7 +216,7 @@ public function getCacheEnabled()

/**
* @return array<string, array<string, int>>
* @psalm-return array<"puts"|"hits"|"misses", array<string, int>>
* @phpstan-return array<"puts"|"hits"|"misses", array<string, int>>
*/
public function getCacheRegions()
{
Expand All @@ -237,7 +237,7 @@ public function getInvalidEntityCount()

/**
* @return string[][]
* @psalm-return array<string, list<QueryType&array{count: int, index: int, executionPercent?: float}>>
* @phpstan-return array<string, list<QueryType&array{count: int, index: int, executionPercent?: float}>>
*/
public function getGroupedQueries()
{
Expand Down
4 changes: 3 additions & 1 deletion src/DependencyInjection/Compiler/DoctrineOrmMappingsPass.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@
public static function createYamlMappingDriver(array $namespaces, array $managerParameters = [], $enabledParameter = false, array $aliasMap = [])
{
$locator = new Definition(SymfonyFileLocator::class, [$namespaces, '.orm.yml']);
$driver = new Definition(YamlDriver::class, [$locator]);
/* @phpstan-ignore class.notFound */
$driver = new Definition(YamlDriver::class, [$locator]);

Check warning on line 93 in src/DependencyInjection/Compiler/DoctrineOrmMappingsPass.php

View check run for this annotation

Codecov / codecov/patch

src/DependencyInjection/Compiler/DoctrineOrmMappingsPass.php#L93

Added line #L93 was not covered by tests

return new DoctrineOrmMappingsPass($driver, $namespaces, $managerParameters, $enabledParameter, $aliasMap);
}
Expand Down Expand Up @@ -133,6 +134,7 @@
public static function createAnnotationMappingDriver(array $namespaces, array $directories, array $managerParameters = [], $enabledParameter = false, array $aliasMap = [], bool $reportFieldsWhereDeclared = false)
{
$reader = new Reference('annotation_reader');
/* @phpstan-ignore class.notFound */
$driver = new Definition(AnnotationDriver::class, [$reader, $directories, $reportFieldsWhereDeclared]);

return new DoctrineOrmMappingsPass($driver, $namespaces, $managerParameters, $enabledParameter, $aliasMap);
Expand Down
6 changes: 4 additions & 2 deletions src/DependencyInjection/DoctrineExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@
* DoctrineExtension is an extension for the Doctrine DBAL and ORM library.
*
* @final since 2.9
* @psalm-type DBALConfig = array{
* @phpstan-type DBALConfig = array{
* connections: array<string, array{logging: bool, profiling: bool, profiling_collect_backtrace: bool, idle_connection_ttl: int}>,
* driver_schemes: array<string, string>,
* default_connection: string,
Expand Down Expand Up @@ -579,7 +579,6 @@ protected function ormLoad(array $config, ContainerBuilder $container)

$entityManagers = [];
foreach (array_keys($config['entity_managers']) as $name) {
/** @psalm-suppress InvalidArrayOffset */
$entityManagers[$name] = sprintf('doctrine.orm.%s_entity_manager', $name);
}

Expand Down Expand Up @@ -1186,12 +1185,15 @@ protected function getMetadataDriverClass(string $driverType): string
return SimplifiedXmlDriver::class;

case 'yml':
/* @phpstan-ignore class.notFound */
return SimplifiedYamlDriver::class;

case 'php':
/* @phpstan-ignore class.notFound */
return class_exists(PHPDriver::class) ? PHPDriver::class : LegacyPHPDriver::class;

case 'staticphp':
/* @phpstan-ignore class.notFound */
return class_exists(StaticPHPDriver::class) ? StaticPHPDriver::class : LegacyStaticPHPDriver::class;

case 'attribute':
Expand Down
2 changes: 2 additions & 0 deletions src/Mapping/DisconnectedMetadataFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ private function getMetadataForNamespace(string $namespace): ClassMetadataCollec
private function getMetadataForClass(string $entity): ClassMetadataCollection
{
foreach ($this->registry->getManagers() as $em) {
/* @phpstan-ignore class.notFound */
$cmf = new DisconnectedClassMetadataFactory();
$cmf->setEntityManager($em);

Expand All @@ -162,6 +163,7 @@ private function getAllMetadata(): array
{
$metadata = [];
foreach ($this->registry->getManagers() as $em) {
/* @phpstan-ignore class.notFound */
$cmf = new DisconnectedClassMetadataFactory();
$cmf->setEntityManager($em);
foreach ($cmf->getAllMetadata() as $m) {
Expand Down
1 change: 0 additions & 1 deletion src/Middleware/BacktraceDebugDataHolder.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

use const DEBUG_BACKTRACE_IGNORE_ARGS;

/** @psalm-suppress MissingDependency */
class BacktraceDebugDataHolder extends DebugDataHolder
{
/** @var string[] */
Expand Down
1 change: 0 additions & 1 deletion src/Middleware/DebugMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ public function setConnectionName(string $name): void

public function wrap(DriverInterface $driver): DriverInterface
{
/** @psalm-suppress InternalClass,InternalMethod */
return new Driver($driver, $this->debugDataHolder, $this->stopwatch, $this->connectionName);
}
}
2 changes: 2 additions & 0 deletions src/Registry.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,12 @@ public function getAliasNamespace($alias)
try {
/** @psalm-suppress UndefinedMethod ORM < 3 specific */
return $objectManager->getConfiguration()->getEntityNamespace($alias);
/* @phpstan-ignore class.notFound */
} catch (ORMException $e) {
}
}

/* @phpstan-ignore class.notFound */
throw ORMException::unknownEntityNamespace($alias);
}

Expand Down
Loading
Loading