Skip to content

Commit f021648

Browse files
committed
Finish up setup of phpstan/phpstan-symfony + cleanup
1 parent 76f9ce6 commit f021648

16 files changed

+92
-118
lines changed

.github/workflows/static-analysis.yml

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,25 @@ on:
2424
- tests/**
2525

2626
jobs:
27-
static-analysis:
28-
name: "Static Analysis"
29-
uses: "doctrine/.github/.github/workflows/[email protected]"
27+
phpstan:
28+
name: "PHPStan"
29+
runs-on: "ubuntu-latest"
30+
31+
steps:
32+
- name: "Checkout code"
33+
uses: "actions/checkout@v5"
34+
35+
- name: "Install PHP"
36+
uses: "shivammathur/setup-php@v2"
37+
with:
38+
coverage: "none"
39+
php-version: "8.4"
40+
41+
- name: "Install dependencies with Composer"
42+
uses: "ramsey/composer-install@v3"
43+
44+
- name: "Warm up Symfony cache"
45+
run: "php tests/console-application.php"
46+
47+
- name: "Run a static analysis with phpstan/phpstan"
48+
run: "vendor/bin/phpstan analyse -v"

phpstan.neon.dist

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,8 @@ parameters:
77
- config
88
- src
99
- tests
10-
ignoreErrors:
11-
- '#Call to method .* on an unknown class Symfony\\Component\\Config\\Definition\\Builder\\.*#'
10+
scanFiles:
11+
- vendor/symfony/dependency-injection/Loader/Configurator/ContainerConfigurator.php
12+
symfony:
13+
constantHassers: false
14+
containerXmlPath: var/cache/test/Doctrine_Bundle_DoctrineBundle_Tests_DependencyInjection_Fixtures_TestKernelTestDebugContainer.xml

src/DataCollector/DoctrineDataCollector.php

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
use Throwable;
1919

2020
use function array_map;
21-
use function array_merge;
2221
use function array_sum;
2322
use function arsort;
2423
use function assert;
@@ -59,7 +58,7 @@
5958
* executionPercent?: float
6059
* }
6160
* @phpstan-type GroupedQueriesType = array<string, array<int, GroupedQueryItemType>>
62-
* @psalm-property DataType $data
61+
* @phpstan-property DataType $data
6362
*/
6463
class DoctrineDataCollector extends BaseCollector
6564
{
@@ -287,11 +286,10 @@ public function getGroupedQueries(): array
287286
foreach ($queries as $i => $query) {
288287
$key = $query['sql'];
289288
if (! isset($connectionGroupedQueries[$key])) {
290-
$connectionGroupedQueries[$key] = array_merge($query, [
291-
'executionMS' => 0,
292-
'count' => 0,
293-
'index' => $i, // "Explain query" relies on query index in 'queries'.
294-
]);
289+
$connectionGroupedQueries[$key] = $query;
290+
$connectionGroupedQueries[$key]['executionMS'] = 0;
291+
$connectionGroupedQueries[$key]['count'] = 0;
292+
$connectionGroupedQueries[$key]['index'] = $i; // "Explain query" relies on query index in 'queries'.
295293
}
296294

297295
$connectionGroupedQueries[$key]['executionMS'] += $query['executionMS'];
@@ -306,9 +304,7 @@ public function getGroupedQueries(): array
306304

307305
return $a['executionMS'] < $b['executionMS'] ? 1 : -1;
308306
});
309-
$sortedQueries = $connectionGroupedQueries;
310-
/** @var array<int, GroupedQueryItemType> $sortedQueries */
311-
$this->groupedQueries[$connection] = $sortedQueries;
307+
$this->groupedQueries[$connection] = $connectionGroupedQueries;
312308
}
313309

314310
foreach ($this->groupedQueries as $connection => $queries) {

src/DependencyInjection/Compiler/MiddlewaresPass.php

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,7 @@ public function process(ContainerBuilder $container): void
4747
}
4848
}
4949

50-
/** @var array<string, string> $connections */
51-
$connections = $container->getParameter('doctrine.connections');
52-
53-
foreach (array_keys($connections) as $name) {
50+
foreach (array_keys($container->getParameter('doctrine.connections')) as $name) {
5451
$middlewareRefs = [];
5552
$i = 0;
5653
foreach ($middlewareAbstractDefs as $id => $abstractDef) {

src/DependencyInjection/Configuration.php

Lines changed: 26 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,7 @@
1111
use InvalidArgumentException;
1212
use RuntimeException;
1313
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
14-
use Symfony\Component\Config\Definition\Builder\ExprBuilder;
15-
use Symfony\Component\Config\Definition\Builder\NodeBuilder;
1614
use Symfony\Component\Config\Definition\Builder\NodeDefinition;
17-
use Symfony\Component\Config\Definition\Builder\NodeParentInterface;
1815
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
1916
use Symfony\Component\Config\Definition\ConfigurationInterface;
2017
use Symfony\Component\DependencyInjection\Exception\LogicException;
@@ -51,7 +48,6 @@ public function __construct(private bool $debug)
5148
{
5249
}
5350

54-
/** @return TreeBuilder<'array'> */
5551
public function getConfigTreeBuilder(): TreeBuilder
5652
{
5753
$treeBuilder = new TreeBuilder('doctrine');
@@ -65,17 +61,16 @@ public function getConfigTreeBuilder(): TreeBuilder
6561

6662
/**
6763
* Add DBAL section to configuration tree
68-
*
69-
* @param ArrayNodeDefinition<TreeBuilder<'array'>> $node
7064
*/
7165
private function addDbalSection(ArrayNodeDefinition $node): void
7266
{
7367
// Key that should not be rewritten to the connection config
7468
$excludedKeys = ['default_connection' => true, 'driver_schemes' => true, 'driver_scheme' => true, 'types' => true, 'type' => true];
7569

76-
$children = $node->children();
77-
/** @var NodeBuilder<ArrayNodeDefinition<NodeParentInterface>> $children */
78-
$children->arrayNode('dbal')
70+
/** @phpstan-ignore class.notFound (Phpstan Symfony extension does not know yet how to deal with these) */
71+
$node
72+
->children()
73+
->arrayNode('dbal')
7974
->beforeNormalization()
8075
->ifTrue(static function ($v) use ($excludedKeys) {
8176
if (! is_array($v)) {
@@ -159,8 +154,6 @@ private function addDbalSection(ArrayNodeDefinition $node): void
159154

160155
/**
161156
* Return the dbal connections node
162-
*
163-
* @return ArrayNodeDefinition<TreeBuilder<'array'>>
164157
*/
165158
private function getDbalConnectionsNode(): ArrayNodeDefinition
166159
{
@@ -174,6 +167,7 @@ private function getDbalConnectionsNode(): ArrayNodeDefinition
174167

175168
$this->configureDbalDriverNode($connectionNode);
176169

170+
/** @phpstan-ignore class.notFound (Phpstan Symfony extension does not know yet how to deal with these) */
177171
$connectionNode
178172
->fixXmlConfig('option')
179173
->fixXmlConfig('mapping_type')
@@ -220,9 +214,9 @@ private function getDbalConnectionsNode(): ArrayNodeDefinition
220214
->scalarNode('result_cache')->end()
221215
->end();
222216

223-
$children = $connectionNode->children();
224-
/** @var NodeBuilder<ArrayNodeDefinition<NodeParentInterface>> $children */
225-
$replicaNode = $children
217+
/** @phpstan-ignore class.notFound (Phpstan Symfony extension does not know yet how to deal with these) */
218+
$replicaNode = $connectionNode
219+
->children()
226220
->arrayNode('replicas')
227221
->useAttributeAsKey('name')
228222
->prototype('array');
@@ -235,16 +229,12 @@ private function getDbalConnectionsNode(): ArrayNodeDefinition
235229
* Adds config keys related to params processed by the DBAL drivers
236230
*
237231
* These keys are available for replica configurations too.
238-
*
239-
* @param ArrayNodeDefinition<TP> $node
240-
*
241-
* @template TP of NodeParentInterface|null
242-
**/
232+
*/
243233
private function configureDbalDriverNode(ArrayNodeDefinition $node): void
244234
{
245-
$validate = $node->validate();
246-
/** @var ExprBuilder<ArrayNodeDefinition<NodeParentInterface>> $validate */
247-
$validate
235+
/** @phpstan-ignore class.notFound (Phpstan Symfony extension does not know yet how to deal with these) */
236+
$node
237+
->validate()
248238
->always(static function (array $values) {
249239
if (! isset($values['url'])) {
250240
return $values;
@@ -265,8 +255,7 @@ private function configureDbalDriverNode(ArrayNodeDefinition $node): void
265255

266256
return $values;
267257
})
268-
->end();
269-
$node
258+
->end()
270259
->children()
271260
->scalarNode('url')->info('A URL with connection information; any parameter value parsed from this string will override explicitly set parameters')->end()
272261
->scalarNode('dbname')->end()
@@ -369,8 +358,6 @@ private function configureDbalDriverNode(ArrayNodeDefinition $node): void
369358

370359
/**
371360
* Add the ORM section to configuration tree
372-
*
373-
* @param ArrayNodeDefinition<TreeBuilder<'array'>> $node
374361
*/
375362
private function addOrmSection(ArrayNodeDefinition $node): void
376363
{
@@ -383,9 +370,9 @@ private function addOrmSection(ArrayNodeDefinition $node): void
383370
'controller_resolver' => true,
384371
];
385372

386-
$children = $node->children();
387-
/** @var NodeBuilder<ArrayNodeDefinition<NodeParentInterface>> $children */
388-
$children
373+
/** @phpstan-ignore class.notFound (Phpstan Symfony extension does not know yet how to deal with these) */
374+
$node
375+
->children()
389376
->arrayNode('orm')
390377
->beforeNormalization()
391378
->ifTrue(static function ($v) use ($excludedKeys) {
@@ -494,7 +481,7 @@ private function getOrmEntityListenersNode(): NodeDefinition
494481
$treeBuilder = new TreeBuilder('entity_listeners');
495482
$node = $treeBuilder->getRootNode();
496483

497-
$normalizer = static function (array $mappings) {
484+
$normalizer = static function ($mappings) {
498485
$entities = [];
499486

500487
foreach ($mappings as $entityClass => $mapping) {
@@ -531,14 +518,13 @@ private function getOrmEntityListenersNode(): NodeDefinition
531518
return ['entities' => $entities];
532519
};
533520

534-
$before = $node->beforeNormalization();
535-
/** @var ExprBuilder<ArrayNodeDefinition<NodeParentInterface>> $before */
536-
$before
521+
/** @phpstan-ignore class.notFound (Phpstan Symfony extension does not know yet how to deal with these) */
522+
$node
523+
->beforeNormalization()
537524
// Yaml normalization
538525
->ifTrue(static fn ($v) => is_array(reset($v)) && is_string(key(reset($v))))
539526
->then($normalizer)
540-
->end();
541-
$node
527+
->end()
542528
->fixXmlConfig('entity', 'entities')
543529
->children()
544530
->arrayNode('entities')
@@ -572,14 +558,13 @@ private function getOrmEntityListenersNode(): NodeDefinition
572558

573559
/**
574560
* Return ORM entity manager node
575-
*
576-
* @return ArrayNodeDefinition<TreeBuilder<'array'>>
577561
*/
578562
private function getOrmEntityManagersNode(): ArrayNodeDefinition
579563
{
580564
$treeBuilder = new TreeBuilder('entity_managers');
581565
$node = $treeBuilder->getRootNode();
582566

567+
/** @phpstan-ignore class.notFound (Phpstan Symfony extension does not know yet how to deal with these) */
583568
$node
584569
->requiresAtLeastOneElement()
585570
->useAttributeAsKey('name')
@@ -748,21 +733,18 @@ private function getOrmEntityManagersNode(): ArrayNodeDefinition
748733

749734
/**
750735
* Return an ORM cache driver node for a given entity manager
751-
*
752-
* @return ArrayNodeDefinition<TreeBuilder<'array'>>
753736
*/
754737
private function getOrmCacheDriverNode(string $name): ArrayNodeDefinition
755738
{
756739
$treeBuilder = new TreeBuilder($name);
757740
$node = $treeBuilder->getRootNode();
758741

759-
$before = $node->beforeNormalization();
760-
/** @var ExprBuilder<ArrayNodeDefinition<NodeParentInterface>> $before */
761-
$before
742+
/** @phpstan-ignore class.notFound (Phpstan Symfony extension does not know yet how to deal with these) */
743+
$node
744+
->beforeNormalization()
762745
->ifString()
763746
->then(static fn ($v): array => ['type' => $v])
764-
->end();
765-
$node
747+
->end()
766748
->children()
767749
->scalarNode('type')->defaultNull()->end()
768750
->scalarNode('id')->end()

src/DependencyInjection/DoctrineExtension.php

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@
7676
use function glob;
7777
use function in_array;
7878
use function interface_exists;
79-
use function is_array;
8079
use function is_dir;
8180
use function is_string;
8281
use function realpath;
@@ -124,7 +123,6 @@ private function loadMappingInformation(array $objectManager, ContainerBuilder $
124123
if ($objectManager['auto_mapping']) {
125124
// automatically register bundle mappings
126125
$bundles = $container->getParameter('kernel.bundles');
127-
assert(is_array($bundles));
128126
foreach (array_keys($bundles) as $bundle) {
129127
if (isset($objectManager['mappings'][$bundle])) {
130128
continue;
@@ -157,10 +155,9 @@ private function loadMappingInformation(array $objectManager, ContainerBuilder $
157155
if ($mappingConfig['is_bundle']) {
158156
$bundle = null;
159157
$bundleMetadata = null;
160-
$kernelBundles = $container->getParameter('kernel.bundles');
161-
assert(is_array($kernelBundles));
158+
/** @var array<string, class-string> $kernelBundles */
159+
$kernelBundles = $container->getParameter('kernel.bundles');
162160
$kernelBundlesMetadata = $container->getParameter('kernel.bundles_metadata');
163-
assert(is_array($kernelBundlesMetadata));
164161
foreach ($kernelBundles as $name => $class) {
165162
if ($mappingName === $name) {
166163
$bundle = new ReflectionClass($class);
@@ -822,8 +819,7 @@ private function ormLoad(array $config, ContainerBuilder $container): void
822819
$container->setAlias('doctrine.orm.entity_manager', $defaultEntityManagerDefinitionId = sprintf('doctrine.orm.%s_entity_manager', $config['default_entity_manager']));
823820
$container->getAlias('doctrine.orm.entity_manager')->setPublic(true);
824821

825-
$bundles = $container->getParameter('kernel.bundles');
826-
assert(is_array($bundles));
822+
$bundles = $container->getParameter('kernel.bundles');
827823
$config['entity_managers'] = $this->fixManagersAutoMappings($config['entity_managers'], $bundles);
828824

829825
foreach ($config['entity_managers'] as $name => $entityManager) {

src/DoctrineBundle.php

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,7 @@ public function shutdown(): void
8080
{
8181
// Clear all entity managers to clear references to entities for GC
8282
if ($this->container->hasParameter('doctrine.entity_managers')) {
83-
/** @var array<string, string> $entityManagers */
84-
$entityManagers = $this->container->getParameter('doctrine.entity_managers');
85-
86-
foreach ($entityManagers as $id) {
83+
foreach ($this->container->getParameter('doctrine.entity_managers') as $id) {
8784
if (! $this->container->initialized($id)) {
8885
continue;
8986
}
@@ -99,10 +96,7 @@ public function shutdown(): void
9996
return;
10097
}
10198

102-
/** @var array<string, string> $connections */
103-
$connections = $this->container->getParameter('doctrine.connections');
104-
105-
foreach ($connections as $id) {
99+
foreach ($this->container->getParameter('doctrine.connections') as $id) {
106100
if (! $this->container->initialized($id)) {
107101
continue;
108102
}

tests/Command/CreateDatabaseDoctrineTest.php

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
use Symfony\Component\DependencyInjection\Container;
1818

1919
use function array_merge;
20-
use function assert;
2120
use function sys_get_temp_dir;
2221
use function unlink;
2322

@@ -41,9 +40,7 @@ public function testExecute(): void
4140
$container = $this->getMockContainer($connectionName, $params);
4241

4342
$application = new SymfonyApp();
44-
$doctrine = $container->get('doctrine');
45-
assert($doctrine instanceof ManagerRegistry);
46-
$application->addCommand(new CreateDatabaseDoctrineCommand($doctrine));
43+
$application->addCommand(new CreateDatabaseDoctrineCommand($container->get('doctrine')));
4744

4845
$command = $application->find('doctrine:database:create');
4946

0 commit comments

Comments
 (0)