Skip to content

Commit 3283adb

Browse files
committed
Hunt down invalid docblocks
It is OK to ignore some of the errors we get, but not this one.
1 parent c78f933 commit 3283adb

File tree

4 files changed

+158
-29
lines changed

4 files changed

+158
-29
lines changed

lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php

+2-4
Original file line numberDiff line numberDiff line change
@@ -1353,7 +1353,7 @@ public function enableAssociationCache($fieldName, array $cache)
13531353
/**
13541354
* @param string $fieldName
13551355
* @param array $cache
1356-
* @psalm-param array{usage?: int, region?: string|null} $cache
1356+
* @psalm-param array{usage?: int|null, region?: string|null} $cache
13571357
*
13581358
* @return int[]|string[]
13591359
* @psalm-return array{usage: int, region: string|null}
@@ -1810,7 +1810,7 @@ protected function validateAndCompleteFieldMapping(array $mapping): array
18101810
* type: int,
18111811
* originalField: string,
18121812
* originalClass: class-string,
1813-
* ?orphanRemoval: bool
1813+
* orphanRemoval?: bool,
18141814
* }
18151815
*
18161816
* @throws MappingException If something is wrong with the mapping.
@@ -1941,7 +1941,6 @@ protected function _validateAndCompleteAssociationMapping(array $mapping)
19411941
* @psalm-param array<string, mixed> $mapping The mapping to validate & complete.
19421942
*
19431943
* @return mixed[] The validated & completed mapping.
1944-
* @psalm-return array{isOwningSide: mixed, orphanRemoval: bool, isCascadeRemove: bool}
19451944
* @psalm-return array{
19461945
* mappedBy: mixed|null,
19471946
* inversedBy: mixed|null,
@@ -2096,7 +2095,6 @@ protected function _validateAndCompleteOneToManyMapping(array $mapping)
20962095
* Validates & completes a many-to-many association mapping.
20972096
*
20982097
* @psalm-param array<string, mixed> $mapping The mapping to validate & complete.
2099-
* @psalm-param array<string, mixed> $mapping The mapping to validate & complete.
21002098
*
21012099
* @return mixed[] The validated & completed mapping.
21022100
* @psalm-return array{

lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php

+5-3
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Symfony\Component\Yaml\Yaml;
1616

1717
use function array_map;
18+
use function assert;
1819
use function class_exists;
1920
use function constant;
2021
use function defined;
@@ -903,11 +904,10 @@ private function columnToArray(string $fieldName, ?array $column): array
903904
* Parse / Normalize the cache configuration
904905
*
905906
* @param mixed[] $cacheMapping
906-
* @psalm-param array{usage: mixed, region: (string|null)} $cacheMapping
907-
* @psalm-param array{usage: string, region?: string} $cacheMapping
907+
* @psalm-param array{usage: string|null, region?: mixed} $cacheMapping
908908
*
909909
* @return mixed[]
910-
* @psalm-return array{usage: int, region: string|null}
910+
* @psalm-return array{usage: int|null, region: string|null}
911911
*/
912912
private function cacheToArray(array $cacheMapping): array
913913
{
@@ -922,6 +922,8 @@ private function cacheToArray(array $cacheMapping): array
922922
$usage = (int) constant('Doctrine\ORM\Mapping\ClassMetadata::CACHE_USAGE_' . $usage);
923923
}
924924

925+
assert($usage !== '0' && $usage !== '');
926+
925927
return [
926928
'usage' => $usage,
927929
'region' => $region,

phpstan-baseline.neon

+80-5
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,21 @@ parameters:
170170
count: 2
171171
path: lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php
172172

173+
-
174+
message: "#^Cannot unset offset 'unique' on array\\{mappedBy\\: mixed, inversedBy\\: mixed, isOwningSide\\: false, sourceEntity\\: class\\-string, targetEntity\\: string, fieldName\\: mixed, fetch\\: mixed, cascade\\: array\\<string\\>, \\.\\.\\.\\}\\|array\\{mappedBy\\: mixed, inversedBy\\: mixed, isOwningSide\\: true, sourceEntity\\: class\\-string, targetEntity\\: string, fieldName\\: mixed, fetch\\: mixed, cascade\\: array\\<string\\>, \\.\\.\\.\\}\\.$#"
175+
count: 1
176+
path: lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
177+
178+
-
179+
message: "#^Else branch is unreachable because previous condition is always true\\.$#"
180+
count: 1
181+
path: lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
182+
183+
-
184+
message: "#^If condition is always false\\.$#"
185+
count: 1
186+
path: lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
187+
173188
-
174189
message: "#^Method Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadataInfo\\:\\:fullyQualifiedClassName\\(\\) should return class\\-string\\|null but returns string\\|null\\.$#"
175190
count: 1
@@ -185,6 +200,71 @@ parameters:
185200
count: 1
186201
path: lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
187202

203+
-
204+
message: "#^Offset 'fieldName' on array\\{name\\: string, referencedColumnName\\: string, unique\\?\\: true, quoted\\?\\: true\\} on left side of \\?\\? does not exist\\.$#"
205+
count: 1
206+
path: lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
207+
208+
-
209+
message: "#^Offset 'id' on array\\{mappedBy\\: mixed, inversedBy\\: mixed, isOwningSide\\: false, sourceEntity\\: class\\-string, targetEntity\\: string, fieldName\\: mixed, fetch\\: mixed, cascade\\: array\\<string\\>, \\.\\.\\.\\}\\|array\\{mappedBy\\: mixed, inversedBy\\: mixed, isOwningSide\\: true, sourceEntity\\: class\\-string, targetEntity\\: string, fieldName\\: mixed, fetch\\: mixed, cascade\\: array\\<string\\>, \\.\\.\\.\\} in isset\\(\\) does not exist\\.$#"
210+
count: 1
211+
path: lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
212+
213+
-
214+
message: "#^Offset 'id' on array\\{mappedBy\\: mixed, inversedBy\\: mixed, isOwningSide\\: true, sourceEntity\\: class\\-string, targetEntity\\: string, fieldName\\: mixed, fetch\\: mixed, cascade\\: array\\<string\\>, \\.\\.\\.\\}\\|array\\{mappedBy\\: mixed, inversedBy\\: mixed, isOwningSide\\: true, sourceEntity\\: class\\-string, targetEntity\\: string, fieldName\\: mixed, fetch\\: mixed, cascade\\: array\\<string\\>, \\.\\.\\.\\} in empty\\(\\) does not exist\\.$#"
215+
count: 1
216+
path: lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
217+
218+
-
219+
message: "#^Offset 'inverseJoinColumns' on array\\{name\\: string, joinColumns\\: array\\{array\\{name\\: string, referencedColumnName\\: string, onDelete\\: 'CASCADE'\\}\\}\\} in isset\\(\\) does not exist\\.$#"
220+
count: 1
221+
path: lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
222+
223+
-
224+
message: "#^Offset 'inverseJoinColumns' on array\\{name\\: string\\} in isset\\(\\) does not exist\\.$#"
225+
count: 1
226+
path: lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
227+
228+
-
229+
message: "#^Offset 'joinColumns' on array\\{mappedBy\\: mixed, inversedBy\\: mixed, isOwningSide\\: bool, sourceEntity\\: class\\-string, targetEntity\\: string, fieldName\\: mixed, fetch\\: mixed, cascade\\: array\\<string\\>, \\.\\.\\.\\} in isset\\(\\) does not exist\\.$#"
230+
count: 1
231+
path: lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
232+
233+
-
234+
message: "#^Offset 'joinColumns' on array\\{mappedBy\\: mixed, inversedBy\\: mixed, isOwningSide\\: true, sourceEntity\\: class\\-string, targetEntity\\: string, fieldName\\: mixed, fetch\\: mixed, cascade\\: array\\<string\\>, \\.\\.\\.\\} in empty\\(\\) does not exist\\.$#"
235+
count: 1
236+
path: lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
237+
238+
-
239+
message: "#^Offset 'joinColumns' on array\\{name\\: string\\} in isset\\(\\) does not exist\\.$#"
240+
count: 2
241+
path: lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
242+
243+
-
244+
message: "#^Offset 'joinTable' on array\\{mappedBy\\: mixed, inversedBy\\: mixed, isOwningSide\\: true, sourceEntity\\: class\\-string, targetEntity\\: string, fieldName\\: mixed, fetch\\: mixed, cascade\\: array\\<string\\>, \\.\\.\\.\\} in isset\\(\\) does not exist\\.$#"
245+
count: 1
246+
path: lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
247+
248+
-
249+
message: "#^Offset 'onDelete' on array\\{name\\: string, referencedColumnName\\: string, onDelete\\: 'CASCADE', quoted\\?\\: true\\} in isset\\(\\) always exists and is not nullable\\.$#"
250+
count: 2
251+
path: lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
252+
253+
-
254+
message: "#^Result of && is always false\\.$#"
255+
count: 3
256+
path: lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
257+
258+
-
259+
message: "#^Result of && is always true\\.$#"
260+
count: 2
261+
path: lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
262+
263+
-
264+
message: "#^Result of \\|\\| is always false\\.$#"
265+
count: 1
266+
path: lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
267+
188268
-
189269
message: "#^Call to an undefined method Doctrine\\\\Persistence\\\\Mapping\\\\ClassMetadata\\:\\:mapEmbedded\\(\\)\\.$#"
190270
count: 1
@@ -230,11 +310,6 @@ parameters:
230310
count: 1
231311
path: lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php
232312

233-
-
234-
message: "#^Offset 'usage' on array\\{usage\\: string, region\\?\\: string\\} in isset\\(\\) always exists and is not nullable\\.$#"
235-
count: 1
236-
path: lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php
237-
238313
-
239314
message: "#^Call to function is_int\\(\\) with string will always evaluate to false\\.$#"
240315
count: 1

psalm-baseline.xml

+71-17
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,9 @@
579579
<file src="lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php">
580580
<ArgumentTypeCoercion>
581581
<code>$mapping</code>
582+
<code>$mapping['targetEntity']</code>
583+
<code>$mapping['targetEntity']</code>
584+
<code>$mapping['targetEntity']</code>
582585
</ArgumentTypeCoercion>
583586
<DeprecatedConstant>
584587
<code>self::GENERATOR_TYPE_UUID</code>
@@ -603,11 +606,11 @@
603606
<code>$mapping</code>
604607
<code>$overrideMapping</code>
605608
</InvalidArgument>
606-
<InvalidDocblock>
607-
<code>protected function _validateAndCompleteAssociationMapping(array $mapping)</code>
608-
<code>protected function _validateAndCompleteManyToManyMapping(array $mapping)</code>
609-
<code>protected function _validateAndCompleteOneToOneMapping(array $mapping)</code>
610-
</InvalidDocblock>
609+
<InvalidArrayOffset>
610+
<code>$mapping['joinColumns']</code>
611+
<code>$mapping['joinTable']</code>
612+
<code>$mapping['unique']</code>
613+
</InvalidArrayOffset>
611614
<InvalidNullableReturnType>
612615
<code>ReflectionProperty</code>
613616
<code>ReflectionProperty</code>
@@ -620,28 +623,85 @@
620623
<code>$this-&gt;subClasses</code>
621624
</InvalidPropertyAssignmentValue>
622625
<InvalidReturnStatement>
626+
<code>$mapping</code>
627+
<code>$mapping</code>
623628
<code>$this-&gt;reflClass</code>
624629
</InvalidReturnStatement>
625630
<InvalidReturnType>
631+
<code>array{
632+
* mappedBy: mixed,
633+
* inversedBy: mixed,
634+
* isOwningSide: bool,
635+
* sourceEntity: string,
636+
* targetEntity: string,
637+
* fieldName: mixed,
638+
* fetch: int|mixed,
639+
* cascade: array&lt;array-key,string&gt;,
640+
* isCascadeRemove: bool,
641+
* isCascadePersist: bool,
642+
* isCascadeRefresh: bool,
643+
* isCascadeMerge: bool,
644+
* isCascadeDetach: bool,
645+
* orphanRemoval: bool
646+
* }</code>
647+
<code>array{
648+
* mappedBy: mixed|null,
649+
* inversedBy: mixed|null,
650+
* isOwningSide: bool,
651+
* sourceEntity: class-string,
652+
* targetEntity: string,
653+
* fieldName: mixed,
654+
* fetch: mixed,
655+
* cascade: array&lt;array-key,string&gt;,
656+
* isCascadeRemove: bool,
657+
* isCascadePersist: bool,
658+
* isCascadeRefresh: bool,
659+
* isCascadeMerge: bool,
660+
* isCascadeDetach: bool,
661+
* type: int,
662+
* originalField: string,
663+
* originalClass: class-string,
664+
* orphanRemoval?: bool,
665+
* }</code>
626666
<code>getReflectionClass</code>
627667
</InvalidReturnType>
628668
<LessSpecificReturnStatement>
629669
<code>$cache</code>
630670
<code>$className</code>
631671
<code>$className</code>
632672
<code>$columnNames</code>
673+
<code>$mapping</code>
633674
<code>$quotedColumnNames</code>
634675
<code>$this-&gt;namespace . '\\' . $className</code>
635676
</LessSpecificReturnStatement>
636677
<MethodSignatureMustProvideReturnType>
637678
<code>__toString</code>
638679
</MethodSignatureMustProvideReturnType>
639-
<MissingReturnType>
640-
<code>_validateAndCompleteAssociationMapping</code>
641-
<code>_validateAndCompleteManyToManyMapping</code>
642-
<code>_validateAndCompleteOneToOneMapping</code>
643-
</MissingReturnType>
644680
<MoreSpecificReturnType>
681+
<code>array{
682+
* mappedBy: mixed|null,
683+
* inversedBy: mixed|null,
684+
* isOwningSide: bool,
685+
* sourceEntity: class-string,
686+
* targetEntity: string,
687+
* fieldName: mixed,
688+
* fetch: mixed,
689+
* cascade: array&lt;string&gt;,
690+
* isCascadeRemove: bool,
691+
* isCascadePersist: bool,
692+
* isCascadeRefresh: bool,
693+
* isCascadeMerge: bool,
694+
* isCascadeDetach: bool,
695+
* type: int,
696+
* originalField: string,
697+
* originalClass: class-string,
698+
* joinColumns?: array{0: array{name: string, referencedColumnName: string}}|mixed,
699+
* id?: mixed,
700+
* sourceToTargetKeyColumns?: array&lt;string, string&gt;,
701+
* joinColumnFieldNames?: array&lt;string, string&gt;,
702+
* targetToSourceKeyColumns?: array&lt;string, string&gt;,
703+
* orphanRemoval: bool
704+
* }</code>
645705
<code>array{usage: int, region: string|null}</code>
646706
<code>class-string|null</code>
647707
<code>list&lt;string&gt;</code>
@@ -687,6 +747,7 @@
687747
<code>$mapping['fieldName']</code>
688748
<code>$mapping['originalClass']</code>
689749
<code>$mapping['originalField']</code>
750+
<code>$mapping['sourceToTargetKeyColumns']</code>
690751
<code>$mapping['targetEntity']</code>
691752
<code>$table['name']</code>
692753
<code>$this-&gt;associationMappings[$assocName]['joinColumns']</code>
@@ -928,10 +989,6 @@
928989
<code>addNamedQuery</code>
929990
</DeprecatedMethod>
930991
<InvalidArgument>
931-
<code>$this-&gt;cacheToArray($manyToManyElement-&gt;cache)</code>
932-
<code>$this-&gt;cacheToArray($manyToOneElement-&gt;cache)</code>
933-
<code>$this-&gt;cacheToArray($oneToManyElement-&gt;cache)</code>
934-
<code>$this-&gt;cacheToArray($oneToOneElement-&gt;cache)</code>
935992
<code>[
936993
'name' =&gt; isset($discrColumn['name']) ? (string) $discrColumn['name'] : null,
937994
'type' =&gt; isset($discrColumn['type']) ? (string) $discrColumn['type'] : 'string',
@@ -1031,9 +1088,6 @@
10311088
'enumType' =&gt; isset($discrColumn['enumType']) ? (string) $discrColumn['enumType'] : null,
10321089
]</code>
10331090
</InvalidArgument>
1034-
<InvalidDocblock>
1035-
<code>private function cacheToArray(array $cacheMapping): array</code>
1036-
</InvalidDocblock>
10371091
<MissingParamType>
10381092
<code>$fileExtension</code>
10391093
<code>$locator</code>

0 commit comments

Comments
 (0)