Skip to content

Commit 946ff86

Browse files
committed
Psalm level 5
It adds a baseline to reach level 5
1 parent 87f0c64 commit 946ff86

28 files changed

+206
-73
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
"phpunit/phpunit": "^8.5 || ^9",
4949
"squizlabs/php_codesniffer": "^3.5",
5050
"symfony/cache": "^4.4 || ^5.0 || ^6.0",
51-
"vimeo/psalm": "^4.8.1"
51+
"vimeo/psalm": "^4.20.0"
5252
},
5353
"suggest": {
5454
"ext-bcmath": "Decimal128 type support"

lib/Doctrine/ODM/MongoDB/Iterator/PrimingIterator.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ final class PrimingIterator implements Iterator
2929
/** @var ReferencePrimer */
3030
private $referencePrimer;
3131

32-
/** @var array<string, callable|null> */
32+
/** @var array<string, callable|true|null> */
3333
private $primers;
3434

3535
/**
@@ -42,9 +42,9 @@ final class PrimingIterator implements Iterator
4242
private $referencesPrimed = false;
4343

4444
/**
45-
* @param \Iterator<mixed, TValue> $iterator
46-
* @param ClassMetadata<TDocument> $class
47-
* @param array<string, callable|null> $primers
45+
* @param \Iterator<mixed, TValue> $iterator
46+
* @param ClassMetadata<TDocument> $class
47+
* @param array<string, callable|true|null> $primers
4848
* @psalm-param Hints $unitOfWorkHints
4949
*/
5050
public function __construct(\Iterator $iterator, ClassMetadata $class, ReferencePrimer $referencePrimer, array $primers, array $unitOfWorkHints = [])

lib/Doctrine/ODM/MongoDB/Mapping/Driver/AttributeReader.php

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,17 @@
2020
*/
2121
final class AttributeReader implements Reader
2222
{
23-
/**
24-
* @param ReflectionClass<object> $class
25-
*/
2623
public function getClassAnnotations(ReflectionClass $class): array
2724
{
2825
return $this->convertToAttributeInstances($class->getAttributes());
2926
}
3027

3128
/**
32-
* @param ReflectionClass<object> $class
29+
* @param class-string<T> $annotationName
30+
*
31+
* @return T|null
32+
*
33+
* @template T
3334
*/
3435
public function getClassAnnotation(ReflectionClass $class, $annotationName)
3536
{
@@ -47,6 +48,13 @@ public function getMethodAnnotations(ReflectionMethod $method): array
4748
return $this->convertToAttributeInstances($method->getAttributes());
4849
}
4950

51+
/**
52+
* @param class-string<T> $annotationName
53+
*
54+
* @return T|null
55+
*
56+
* @template T
57+
*/
5058
public function getMethodAnnotation(ReflectionMethod $method, $annotationName)
5159
{
5260
foreach ($this->getMethodAnnotations($method) as $annotation) {
@@ -63,6 +71,13 @@ public function getPropertyAnnotations(ReflectionProperty $property): array
6371
return $this->convertToAttributeInstances($property->getAttributes());
6472
}
6573

74+
/**
75+
* @param class-string<T> $annotationName
76+
*
77+
* @return T|null
78+
*
79+
* @template T
80+
*/
6681
public function getPropertyAnnotation(ReflectionProperty $property, $annotationName)
6782
{
6883
foreach ($this->getPropertyAnnotations($property) as $annotation) {

lib/Doctrine/ODM/MongoDB/Mapping/Driver/XmlDriver.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,7 @@ private function addIndex(ClassMetadata $class, SimpleXMLElement $xmlIndex): voi
571571
}
572572

573573
/**
574-
* @return array<string, array<string, mixed>|scalar>
574+
* @return array<string, array<string, mixed>|scalar|null>
575575
*/
576576
private function getPartialFilterExpression(SimpleXMLElement $fields): array
577577
{

lib/Doctrine/ODM/MongoDB/PersistentCollection/PersistentCollectionTrait.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,7 @@ public function isEmpty()
428428

429429
/**
430430
* @return Traversable
431+
* @psalm-return Traversable<TKey, T>
431432
*/
432433
#[ReturnTypeWillChange]
433434
public function getIterator()
@@ -540,6 +541,7 @@ public function offsetExists($offset)
540541
* @param mixed $offset
541542
*
542543
* @return mixed
544+
* @psalm-return T|null
543545
*/
544546
#[ReturnTypeWillChange]
545547
public function offsetGet($offset)
@@ -660,6 +662,11 @@ private function doAdd($value, $arrayAccess)
660662
* @param mixed $offset
661663
*
662664
* @return bool|T|null
665+
* @psalm-return (
666+
* $arrayAccess is false
667+
* ? T|null
668+
* : T|null|true
669+
* )
663670
*/
664671
private function doRemove($offset, bool $arrayAccess)
665672
{

lib/Doctrine/ODM/MongoDB/Proxy/Factory/StaticProxyFactory.php

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,9 @@ public function generateProxyClasses(array $classes): int
7070
->proxyFactory
7171
->createProxy(
7272
$metadata->getName(),
73-
static function () {
73+
static function (): bool {
7474
// empty closure, serves its purpose, for now
75+
return true;
7576
},
7677
[
7778
'skippedProperties' => $this->skippedFieldsFqns($metadata),
@@ -83,10 +84,18 @@ static function () {
8384
}
8485

8586
/**
86-
* @param ClassMetadata<T> $metadata
87-
* @param DocumentPersister<T> $documentPersister
87+
* @param ClassMetadata<TDocument> $metadata
88+
* @param DocumentPersister<TDocument> $documentPersister
8889
*
89-
* @template T of object
90+
* @psalm-return Closure(
91+
* TDocument&GhostObjectInterface<TDocument>,
92+
* string,
93+
* array<string, mixed>,
94+
* ?Closure=,
95+
* array<string, mixed>
96+
* ) : bool
97+
*
98+
* @template TDocument of object
9099
*/
91100
private function createInitializer(
92101
ClassMetadata $metadata,

phpstan-baseline.neon

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -153,11 +153,6 @@ parameters:
153153
count: 1
154154
path: tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM88Test.php
155155

156-
-
157-
message: "#^Call to an undefined method Doctrine\\\\Persistence\\\\Mapping\\\\ClassMetadata\\<object\\>\\:\\:mapField\\(\\)\\.$#"
158-
count: 1
159-
path: tests/Doctrine/ODM/MongoDB/Tests/Mapping/ClassMetadataLoadEventTest.php
160-
161156
-
162157
message: "#^Parameter \\#1 \\$primer of method Doctrine\\\\ODM\\\\MongoDB\\\\Query\\\\Builder\\:\\:prime\\(\\) expects bool\\|\\(callable\\(\\)\\: mixed\\), 1 given\\.$#"
163158
count: 1

psalm-baseline.xml

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<files psalm-version="4.20.0@f82a70e7edfc6cf2705e9374c8a0b6a974a779ed">
3+
<file src="lib/Doctrine/ODM/MongoDB/Aggregation/Stage/GeoNear.php">
4+
<InvalidReturnStatement occurrences="1">
5+
<code>$this-&gt;num($limit)</code>
6+
</InvalidReturnStatement>
7+
<InvalidReturnType occurrences="1">
8+
<code>self</code>
9+
</InvalidReturnType>
10+
</file>
11+
<file src="lib/Doctrine/ODM/MongoDB/Mapping/ClassMetadata.php">
12+
<InvalidArrayOffset occurrences="1">
13+
<code>[$this-&gt;identifier =&gt; $this-&gt;getIdentifierValue($object)]</code>
14+
</InvalidArrayOffset>
15+
</file>
16+
<file src="lib/Doctrine/ODM/MongoDB/Mapping/Driver/XmlDriver.php">
17+
<InvalidArgument occurrences="1">
18+
<code>$mapping</code>
19+
</InvalidArgument>
20+
</file>
21+
<file src="lib/Doctrine/ODM/MongoDB/PersistentCollection/AbstractPersistentCollectionFactory.php">
22+
<InvalidArgument occurrences="1">
23+
<code>new PersistentCollection($coll, $dm, $dm-&gt;getUnitOfWork())</code>
24+
</InvalidArgument>
25+
</file>
26+
<file src="lib/Doctrine/ODM/MongoDB/PersistentCollection/PersistentCollectionTrait.php">
27+
<InvalidArgument occurrences="5">
28+
<code>$func</code>
29+
<code>$p</code>
30+
<code>$p</code>
31+
<code>$p</code>
32+
<code>$p</code>
33+
</InvalidArgument>
34+
<InvalidNullableReturnType occurrences="1">
35+
<code>getMapping</code>
36+
</InvalidNullableReturnType>
37+
<InvalidReturnType occurrences="1">
38+
<code>getTypeClass</code>
39+
</InvalidReturnType>
40+
</file>
41+
<file src="lib/Doctrine/ODM/MongoDB/Proxy/Resolver/ProxyManagerClassNameResolver.php">
42+
<MoreSpecificImplementedParamType occurrences="1">
43+
<code>$className</code>
44+
</MoreSpecificImplementedParamType>
45+
</file>
46+
<file src="lib/Doctrine/ODM/MongoDB/Repository/DefaultGridFSRepository.php">
47+
<InvalidReturnStatement occurrences="1">
48+
<code>$options + ['metadata' =&gt; (object) $metadata]</code>
49+
</InvalidReturnStatement>
50+
</file>
51+
<file src="lib/Doctrine/ODM/MongoDB/UnitOfWork.php">
52+
<InvalidPropertyAssignmentValue occurrences="2">
53+
<code>$this-&gt;identityMap</code>
54+
<code>$this-&gt;originalDocumentData</code>
55+
</InvalidPropertyAssignmentValue>
56+
<NullableReturnStatement occurrences="1">
57+
<code>$mapping['targetDocument']</code>
58+
</NullableReturnStatement>
59+
</file>
60+
<file src="tests/Doctrine/ODM/MongoDB/Tests/DocumentRepositoryTest.php">
61+
<InvalidArgument occurrences="1">
62+
<code>new ArrayCollection([$project])</code>
63+
</InvalidArgument>
64+
</file>
65+
<file src="tests/Doctrine/ODM/MongoDB/Tests/Functional/CollectionPersisterTest.php">
66+
<InvalidArgument occurrences="3">
67+
<code>[$user-&gt;categories[0]-&gt;children, $user-&gt;categories[1]-&gt;children]</code>
68+
<code>[$user-&gt;categories[0]-&gt;children[0]-&gt;children, $user-&gt;categories[0]-&gt;children[1]-&gt;children]</code>
69+
<code>[$user-&gt;categories[0]-&gt;children[0]-&gt;children, $user-&gt;categories[0]-&gt;children[1]-&gt;children]</code>
70+
</InvalidArgument>
71+
</file>
72+
<file src="tests/Doctrine/ODM/MongoDB/Tests/Functional/CustomCollectionsTest.php">
73+
<InvalidArgument occurrences="4">
74+
<code>$i</code>
75+
<code>$i</code>
76+
<code>$j</code>
77+
<code>$j</code>
78+
</InvalidArgument>
79+
</file>
80+
<file src="tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM81Test.php">
81+
<InvalidNullableReturnType occurrences="1">
82+
<code>DocumentManager</code>
83+
</InvalidNullableReturnType>
84+
<NullableReturnStatement occurrences="1">
85+
<code>$this-&gt;dm</code>
86+
</NullableReturnStatement>
87+
</file>
88+
</files>

psalm.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
<?xml version="1.0"?>
22
<psalm
3-
errorLevel="7"
3+
errorLevel="5"
44
findUnusedPsalmSuppress="true"
55
resolveFromConfigFile="true"
66
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
77
xmlns="https://getpsalm.org/schema/config"
88
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
9+
errorBaseline="psalm-baseline.xml"
910
>
1011
<projectFiles>
1112
<directory name="lib/Doctrine/ODM/MongoDB" />

tests/Doctrine/ODM/MongoDB/Tests/Functional/CommitImprovementTest.php

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -101,17 +101,21 @@ public function testChangingCollectionInPostEventsHasNoIllEffects(): void
101101
$this->dm->persist($user);
102102
$this->dm->flush();
103103

104-
$this->assertCount(1, $user->getPhonenumbers()); // so we got a number on postPersist
105-
$this->assertInstanceOf(PersistentCollectionInterface::class, $user->getPhonenumbers()); // so we got a number on postPersist
106-
$this->assertTrue($user->getPhonenumbers()->isDirty()); // but they should be dirty
104+
$phoneNumbers = $user->getPhonenumbers();
105+
$this->assertCount(1, $phoneNumbers); // so we got a number on postPersist
106+
$this->assertInstanceOf(PersistentCollectionInterface::class, $phoneNumbers); // so we got a number on postPersist
107+
$this->assertTrue($phoneNumbers->isDirty()); // but they should be dirty
107108

108109
$collection = $this->dm->getDocumentCollection(get_class($user));
109110
$inDb = $collection->findOne();
110111
$this->assertArrayNotHasKey('phonenumbers', $inDb, 'Collection modified in postPersist should not be in database without recomputing change set');
111112

112113
$this->dm->flush();
113-
$this->assertCount(2, $user->getPhonenumbers()); // so we got a number on postUpdate
114-
$this->assertTrue($user->getPhonenumbers()->isDirty()); // but they should be dirty
114+
115+
$phoneNumbers = $user->getPhonenumbers();
116+
$this->assertInstanceOf(PersistentCollectionInterface::class, $phoneNumbers);
117+
$this->assertCount(2, $phoneNumbers); // so we got a number on postUpdate
118+
$this->assertTrue($phoneNumbers->isDirty()); // but they should be dirty
115119

116120
$inDb = $collection->findOne();
117121
$this->assertCount(1, $inDb['phonenumbers'], 'Collection changes from postUpdate should not be in database');

0 commit comments

Comments
 (0)