Skip to content

Commit 1f47699

Browse files
committed
fix: satisfy PHPStan 8.5 strict nullable-offset analysis
PHPStan on PHP 8.5 is stricter about array-offset access when the key type includes null. Three pre-existing call sites tripped the new offsetAccess.invalidOffset rule; all three are safe to tighten without behavior change on any supported PHP version (8.2+). FieldsBuilder::mapDocBlock — skip @param tags with no variable name (phpdocumentor returns null there) instead of silently coercing null into an empty-string key. GlobTypeMapperCache::registerAnnotations — GlobAnnotationsCache's withType() sets typeClassName and typeName together, so inside the `typeClassName !== null` branch typeName is guaranteed non-null. Add an assert() to document the invariant for the analyser. IteratorTypeMapper::splitIteratorFromOtherTypes — restructure so the unset/return happens inside the loop where $key has a concrete array-key type, instead of carrying a nullable $key across the loop/early-return boundary. Also drops the unused null initializer.
1 parent 1c60784 commit 1f47699

3 files changed

Lines changed: 17 additions & 13 deletions

File tree

src/FieldsBuilder.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -878,7 +878,13 @@ private function mapParameters(
878878

879879
$docBlockTypes = [];
880880
foreach ($paramTags as $paramTag) {
881-
$docBlockTypes[$paramTag->getVariableName()] = $paramTag->getType();
881+
$variableName = $paramTag->getVariableName();
882+
// Skip malformed @param tags with no variable name (phpdocumentor returns null for
883+
// those). PHPStan 8.5 rejects the implicit null-to-empty-string coercion.
884+
if ($variableName === null) {
885+
continue;
886+
}
887+
$docBlockTypes[$variableName] = $paramTag->getType();
882888
}
883889

884890
$parameterAnnotationsPerParameter = $this->annotationReader->getParameterAnnotationsPerParameter($refParameters);

src/Mappers/GlobTypeMapperCache.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,11 @@ public function registerAnnotations(ReflectionClass|string $sourceClass, GlobAnn
4848
$this->mapClassToTypeArray[$objectClassName] = $className;
4949
}
5050

51+
// GlobAnnotationsCache::withType() sets typeClassName and typeName together, so
52+
// inside this branch typeName is guaranteed non-null. Assert the invariant for PHPStan
53+
// 8.5+, which is stricter about nullable array offsets.
5154
$typeName = $globAnnotationsCache->getTypeName();
55+
assert($typeName !== null);
5256
$this->mapNameToType[$typeName] = $className;
5357
}
5458

src/Mappers/Root/IteratorTypeMapper.php

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -206,8 +206,6 @@ private function toGraphQLType(Compound $type, Closure $topToGraphQLType, bool $
206206
*/
207207
private function splitIteratorFromOtherTypes(array &$types): Type|null
208208
{
209-
$iteratorType = null;
210-
$key = null;
211209
foreach ($types as $key => $singleDocBlockType) {
212210
if (! ($singleDocBlockType instanceof Object_)) {
213211
continue;
@@ -216,21 +214,17 @@ private function splitIteratorFromOtherTypes(array &$types): Type|null
216214
/** @var class-string<object> $fqcn */
217215
$fqcn = (string) $singleDocBlockType->getFqsen();
218216
$refClass = new ReflectionClass($fqcn);
219-
// Note : $refClass->isIterable() is only accessible in PHP 7.2
220217
if (! $refClass->implementsInterface(Iterator::class) && ! $refClass->implementsInterface(IteratorAggregate::class)) {
221218
continue;
222219
}
223-
$iteratorType = $singleDocBlockType;
224-
break;
225-
}
226220

227-
if ($iteratorType === null) {
228-
return null;
229-
}
221+
// One of the classes in the compound is an iterator. Remove it and let the caller
222+
// test the remaining values as potential subTypes.
223+
unset($types[$key]);
230224

231-
// One of the classes in the compound is an iterator. Let's remove it from the list and let's test all other values as potential subTypes.
232-
unset($types[$key]);
225+
return $singleDocBlockType;
226+
}
233227

234-
return $iteratorType;
228+
return null;
235229
}
236230
}

0 commit comments

Comments
 (0)