Skip to content

Commit c7a50a7

Browse files
committed
Help psalm to detect enum varaiables and avoid the More/LessSpecificReturn exceptions
1 parent a4e9c7b commit c7a50a7

39 files changed

+136
-242
lines changed

psalm.baseline.xml

Lines changed: 0 additions & 232 deletions
Original file line numberDiff line numberDiff line change
@@ -88,186 +88,6 @@
8888
<code>getRows</code>
8989
</PossiblyNullReference>
9090
</file>
91-
<file src="src/Service/CloudFormation/src/Result/DescribeStacksOutput.php">
92-
<LessSpecificReturnStatement>
93-
<code>$items</code>
94-
</LessSpecificReturnStatement>
95-
<MoreSpecificReturnType>
96-
<code><![CDATA[list<Capability::*>]]></code>
97-
</MoreSpecificReturnType>
98-
</file>
99-
<file src="src/Service/CodeBuild/src/Result/BatchGetBuildsOutput.php">
100-
<LessSpecificReturnStatement>
101-
<code>$items</code>
102-
</LessSpecificReturnStatement>
103-
<MoreSpecificReturnType>
104-
<code><![CDATA[list<CacheMode::*>]]></code>
105-
</MoreSpecificReturnType>
106-
</file>
107-
<file src="src/Service/CodeBuild/src/Result/StartBuildOutput.php">
108-
<LessSpecificReturnStatement>
109-
<code>$items</code>
110-
</LessSpecificReturnStatement>
111-
<MoreSpecificReturnType>
112-
<code><![CDATA[list<CacheMode::*>]]></code>
113-
</MoreSpecificReturnType>
114-
</file>
115-
<file src="src/Service/CodeBuild/src/Result/StopBuildOutput.php">
116-
<LessSpecificReturnStatement>
117-
<code>$items</code>
118-
</LessSpecificReturnStatement>
119-
<MoreSpecificReturnType>
120-
<code><![CDATA[list<CacheMode::*>]]></code>
121-
</MoreSpecificReturnType>
122-
</file>
123-
<file src="src/Service/CodeDeploy/src/Result/GetDeploymentOutput.php">
124-
<LessSpecificReturnStatement>
125-
<code>$items</code>
126-
</LessSpecificReturnStatement>
127-
<MoreSpecificReturnType>
128-
<code><![CDATA[list<AutoRollbackEvent::*>]]></code>
129-
</MoreSpecificReturnType>
130-
</file>
131-
<file src="src/Service/Kinesis/src/Result/DescribeStreamOutput.php">
132-
<LessSpecificReturnStatement>
133-
<code>$items</code>
134-
</LessSpecificReturnStatement>
135-
<MoreSpecificReturnType>
136-
<code><![CDATA[list<MetricsName::*>]]></code>
137-
</MoreSpecificReturnType>
138-
</file>
139-
<file src="src/Service/Kinesis/src/Result/DescribeStreamSummaryOutput.php">
140-
<LessSpecificReturnStatement>
141-
<code>$items</code>
142-
</LessSpecificReturnStatement>
143-
<MoreSpecificReturnType>
144-
<code><![CDATA[list<MetricsName::*>]]></code>
145-
</MoreSpecificReturnType>
146-
</file>
147-
<file src="src/Service/Kinesis/src/Result/EnhancedMonitoringOutput.php">
148-
<LessSpecificReturnStatement>
149-
<code>$items</code>
150-
</LessSpecificReturnStatement>
151-
<MoreSpecificReturnType>
152-
<code><![CDATA[list<MetricsName::*>]]></code>
153-
</MoreSpecificReturnType>
154-
</file>
155-
<file src="src/Service/Kms/src/Result/CreateKeyResponse.php">
156-
<LessSpecificReturnStatement>
157-
<code>$items</code>
158-
<code>$items</code>
159-
<code>$items</code>
160-
<code>$items</code>
161-
</LessSpecificReturnStatement>
162-
<MoreSpecificReturnType>
163-
<code><![CDATA[list<EncryptionAlgorithmSpec::*>]]></code>
164-
<code><![CDATA[list<MacAlgorithmSpec::*>]]></code>
165-
<code><![CDATA[list<SigningAlgorithmSpec::*>]]></code>
166-
<code><![CDATA[list<KeyAgreementAlgorithmSpec::*>]]></code>
167-
</MoreSpecificReturnType>
168-
</file>
169-
<file src="src/Service/Lambda/src/Result/ListFunctionsResponse.php">
170-
<LessSpecificReturnStatement>
171-
<code>$items</code>
172-
</LessSpecificReturnStatement>
173-
<MoreSpecificReturnType>
174-
<code><![CDATA[list<Architecture::*>]]></code>
175-
</MoreSpecificReturnType>
176-
</file>
177-
<file src="src/Service/Lambda/src/Result/ListLayerVersionsResponse.php">
178-
<LessSpecificReturnStatement>
179-
<code>$items</code>
180-
<code>$items</code>
181-
</LessSpecificReturnStatement>
182-
<MoreSpecificReturnType>
183-
<code><![CDATA[list<Architecture::*>]]></code>
184-
<code><![CDATA[list<Runtime::*>]]></code>
185-
</MoreSpecificReturnType>
186-
</file>
187-
<file src="src/Service/Lambda/src/Result/ListVersionsByFunctionResponse.php">
188-
<LessSpecificReturnStatement>
189-
<code>$items</code>
190-
</LessSpecificReturnStatement>
191-
<MoreSpecificReturnType>
192-
<code><![CDATA[list<Architecture::*>]]></code>
193-
</MoreSpecificReturnType>
194-
</file>
195-
<file src="src/Service/Lambda/src/Result/PublishLayerVersionResponse.php">
196-
<LessSpecificReturnStatement>
197-
<code>$items</code>
198-
<code>$items</code>
199-
</LessSpecificReturnStatement>
200-
<MoreSpecificReturnType>
201-
<code><![CDATA[list<Architecture::*>]]></code>
202-
<code><![CDATA[list<Runtime::*>]]></code>
203-
</MoreSpecificReturnType>
204-
</file>
205-
<file src="src/Service/MediaConvert/src/Result/CreateJobResponse.php">
206-
<LessSpecificReturnStatement>
207-
<code>$items</code>
208-
<code>$items</code>
209-
<code>$items</code>
210-
<code>$items</code>
211-
</LessSpecificReturnStatement>
212-
<MoreSpecificReturnType>
213-
<code><![CDATA[list<AudioChannelTag::*>]]></code>
214-
<code><![CDATA[list<HlsAdMarkers::*>]]></code>
215-
<code><![CDATA[list<TeletextPageType::*>]]></code>
216-
<code><![CDATA[list<FrameMetricType::*>]]></code>
217-
</MoreSpecificReturnType>
218-
</file>
219-
<file src="src/Service/MediaConvert/src/Result/GetJobResponse.php">
220-
<LessSpecificReturnStatement>
221-
<code>$items</code>
222-
<code>$items</code>
223-
<code>$items</code>
224-
<code>$items</code>
225-
</LessSpecificReturnStatement>
226-
<MoreSpecificReturnType>
227-
<code><![CDATA[list<AudioChannelTag::*>]]></code>
228-
<code><![CDATA[list<HlsAdMarkers::*>]]></code>
229-
<code><![CDATA[list<TeletextPageType::*>]]></code>
230-
<code><![CDATA[list<FrameMetricType::*>]]></code>
231-
</MoreSpecificReturnType>
232-
</file>
233-
<file src="src/Service/MediaConvert/src/Result/ListJobsResponse.php">
234-
<LessSpecificReturnStatement>
235-
<code>$items</code>
236-
<code>$items</code>
237-
<code>$items</code>
238-
<code>$items</code>
239-
</LessSpecificReturnStatement>
240-
<MoreSpecificReturnType>
241-
<code><![CDATA[list<AudioChannelTag::*>]]></code>
242-
<code><![CDATA[list<HlsAdMarkers::*>]]></code>
243-
<code><![CDATA[list<TeletextPageType::*>]]></code>
244-
<code><![CDATA[list<FrameMetricType::*>]]></code>
245-
</MoreSpecificReturnType>
246-
</file>
247-
<file src="src/Service/Rekognition/src/Result/IndexFacesResponse.php">
248-
<LessSpecificReturnStatement>
249-
<code>$items</code>
250-
</LessSpecificReturnStatement>
251-
<MoreSpecificReturnType>
252-
<code><![CDATA[list<Reason::*>]]></code>
253-
</MoreSpecificReturnType>
254-
</file>
255-
<file src="src/Service/S3/src/Result/ListObjectsV2Output.php">
256-
<LessSpecificReturnStatement>
257-
<code>$items</code>
258-
</LessSpecificReturnStatement>
259-
<MoreSpecificReturnType>
260-
<code><![CDATA[list<ChecksumAlgorithm::*>]]></code>
261-
</MoreSpecificReturnType>
262-
</file>
263-
<file src="src/Service/S3/src/Result/ListObjectVersionsOutput.php">
264-
<LessSpecificReturnStatement>
265-
<code>$items</code>
266-
</LessSpecificReturnStatement>
267-
<MoreSpecificReturnType>
268-
<code><![CDATA[list<ChecksumAlgorithm::*>]]></code>
269-
</MoreSpecificReturnType>
270-
</file>
27191
<file src="src/Service/S3/src/Signer/SignerV4ForS3.php">
27292
<InvalidArgument>
27393
<code>array_keys($s3SignerOptions)</code>
@@ -289,56 +109,4 @@
289109
<code><![CDATA[$d = \DateTimeImmutable::createFromFormat('U.u', \sprintf('%.6F', $data['stopDate']))]]></code>
290110
</PossiblyFalsePropertyAssignmentValue>
291111
</file>
292-
<file src="src/Service/Sqs/src/Result/GetQueueAttributesResult.php">
293-
<LessSpecificReturnStatement>
294-
<code>$items</code>
295-
</LessSpecificReturnStatement>
296-
<MoreSpecificReturnType>
297-
<code><![CDATA[array<QueueAttributeName::*, string>]]></code>
298-
</MoreSpecificReturnType>
299-
</file>
300-
<file src="src/Service/Sqs/src/Result/ReceiveMessageResult.php">
301-
<LessSpecificReturnStatement>
302-
<code>$items</code>
303-
</LessSpecificReturnStatement>
304-
<MoreSpecificReturnType>
305-
<code><![CDATA[array<MessageSystemAttributeName::*, string>]]></code>
306-
</MoreSpecificReturnType>
307-
</file>
308-
<file src="src/Service/Lambda/src/Result/FunctionConfiguration.php">
309-
<LessSpecificReturnStatement>
310-
<code><![CDATA[$items]]></code>
311-
</LessSpecificReturnStatement>
312-
<MoreSpecificReturnType>
313-
<code><![CDATA[list<Architecture::*>]]></code>
314-
</MoreSpecificReturnType>
315-
</file>
316-
<file src="src/Service/CognitoIdentityProvider/src/Result/InitiateAuthResponse.php">
317-
<LessSpecificReturnStatement>
318-
<code><![CDATA[$items]]></code>
319-
</LessSpecificReturnStatement>
320-
<MoreSpecificReturnType>
321-
<code><![CDATA[list<ChallengeNameType::*>]]></code>
322-
</MoreSpecificReturnType>
323-
</file>
324-
<file src="src/Service/CognitoIdentityProvider/src/Result/AdminInitiateAuthResponse.php">
325-
<LessSpecificReturnStatement>
326-
<code><![CDATA[$items]]></code>
327-
</LessSpecificReturnStatement>
328-
<MoreSpecificReturnType>
329-
<code><![CDATA[list<ChallengeNameType::*>]]></code>
330-
</MoreSpecificReturnType>
331-
</file>
332-
<file src="src/Service/Kms/src/Result/GetPublicKeyResponse.php">
333-
<LessSpecificReturnStatement>
334-
<code><![CDATA[$items]]></code>
335-
<code><![CDATA[$items]]></code>
336-
<code><![CDATA[$items]]></code>
337-
</LessSpecificReturnStatement>
338-
<MoreSpecificReturnType>
339-
<code><![CDATA[list<EncryptionAlgorithmSpec::*>]]></code>
340-
<code><![CDATA[list<KeyAgreementAlgorithmSpec::*>]]></code>
341-
<code><![CDATA[list<SigningAlgorithmSpec::*>]]></code>
342-
</MoreSpecificReturnType>
343-
</file>
344112
</files>

src/CodeGenerator/src/Generator/ResponseParser/RestJsonParser.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,7 @@ private function parseResponseList(ListShape $shape, string $input, bool $requir
303303
if (!isset($this->generatedFunctions[$functionName])) {
304304
// prevent recursion
305305
$this->generatedFunctions[$functionName] = true;
306+
$docBloc = '';
306307

307308
if ($shapeMember->getShape() instanceof StructureShape || $shapeMember->getShape() instanceof ListShape || $shapeMember->getShape() instanceof MapShape) {
308309
$listAccessorRequired = true;
@@ -314,10 +315,17 @@ private function parseResponseList(ListShape $shape, string $input, bool $requir
314315
315316
return $items;';
316317
} else {
318+
if (!empty($shapeMember->getShape()->getEnum())) {
319+
$className = $this->namespaceRegistry->getEnum($shapeMember->getShape());
320+
$docBloc = '/** @var null|'.$className->getName().'::* $a */';
321+
$this->imports[] = $className;
322+
}
323+
317324
$listAccessorRequired = false;
318325
$body = '
319326
$items = [];
320327
foreach (INPUT_PROPERTY as $item) {
328+
DOC_BLOC
321329
$a = LIST_ACCESSOR;
322330
if (null !== $a) {
323331
$items[] = $a;
@@ -330,6 +338,7 @@ private function parseResponseList(ListShape $shape, string $input, bool $requir
330338
$this->functions[$functionName] = $this->createPopulateMethod($functionName, strtr($body, [
331339
'LIST_ACCESSOR' => $this->parseElement('$item', $shapeMember->getShape(), $listAccessorRequired, $inObject),
332340
'INPUT_PROPERTY' => $shape->isFlattened() ? '$json' : '$json' . ($shapeMember->getLocationName() ? '->' . $shapeMember->getLocationName() : ''),
341+
'DOC_BLOC' => $docBloc,
333342
]), $shape);
334343
}
335344

@@ -350,31 +359,42 @@ private function parseResponseMap(MapShape $shape, string $input, bool $required
350359
$this->generatedFunctions[$functionName] = true;
351360

352361
if (null === $locationName = $shape->getKey()->getLocationName()) {
362+
$docBloc = '';
363+
if (!empty($shape->getKey()->getShape()->getEnum())) {
364+
$className = $this->namespaceRegistry->getEnum($shape->getKey()->getShape());
365+
$docBloc = '/** @var '.$className->getName().'::* $name */';
366+
$this->imports[] = $className;
367+
}
368+
353369
// We need to use array keys
354370
if ($shapeValue->getShape() instanceof StructureShape) {
355371
$body = '
356372
$items = [];
357373
foreach ($json as $name => $value) {
374+
DOC_BLOC
358375
$items[(string) $name] = BUILDER_CODE;
359376
}
360377
361378
return $items;
362379
';
363380

364381
$this->functions[$functionName] = $this->createPopulateMethod($functionName, strtr($body, [
382+
'DOC_BLOC' => $docBloc,
365383
'BUILDER_CODE' => $this->parseResponseStructure($shapeValue->getShape(), '$value', true),
366384
]), $shape);
367385
} else {
368386
$body = '
369387
$items = [];
370388
foreach ($json as $name => $value) {
389+
DOC_BLOC
371390
$items[(string) $name] = CODE;
372391
}
373392
374393
return $items;
375394
';
376395

377396
$this->functions[$functionName] = $this->createPopulateMethod($functionName, strtr($body, [
397+
'DOC_BLOC' => $docBloc,
378398
'CODE' => $this->parseElement('$value', $shapeValue->getShape(), true, $inObject),
379399
]), $shape);
380400
}

src/CodeGenerator/src/Generator/ResponseParser/RestXmlParser.php

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -322,19 +322,37 @@ private function parseXmlResponseList(ListShape $shape, string $input, bool $req
322322
';
323323
} else {
324324
$listAccessorRequired = true;
325-
$body = '
326-
$items = [];
327-
foreach (INPUT_PROPERTY as $item) {
328-
$items[] = LIST_ACCESSOR;
329-
}
330325

331-
return $items;
332-
';
326+
if (!empty($shapeMember->getShape()->getEnum())) {
327+
$className = $this->namespaceRegistry->getEnum($shapeMember->getShape());
328+
$this->imports[] = $className;
329+
330+
$body = '
331+
$items = [];
332+
foreach (INPUT_PROPERTY as $item) {
333+
$a = LIST_ACCESSOR;
334+
/** @var ENUM_NAME::* $a */
335+
$items[] = $a;
336+
}
337+
338+
return $items;
339+
';
340+
} else {
341+
$body = '
342+
$items = [];
343+
foreach (INPUT_PROPERTY as $item) {
344+
$items[] = LIST_ACCESSOR;
345+
}
346+
347+
return $items;
348+
';
349+
}
333350
}
334351

335352
$this->functions[$functionName] = $this->createPopulateMethod($functionName, strtr($body, [
336353
'LIST_ACCESSOR' => $this->parseXmlElement('$item', $shapeMember->getShape(), $listAccessorRequired, $inObject),
337354
'INPUT_PROPERTY' => $shape->isFlattened() ? '$xml' : ('$xml->' . ($shapeMember->getLocationName() ? $shapeMember->getLocationName() : 'member')),
355+
'ENUM_NAME' => $this->namespaceRegistry->getEnum($shapeMember->getShape())->getName(),
338356
]), $shape);
339357
}
340358

src/Service/CloudFormation/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## NOT RELEASED
44

5+
### Changed
6+
7+
- Add DocBlock on array's items to help avoid psalm exceptions
8+
59
## 1.9.0
610

711
### Added

src/Service/CloudFormation/src/Result/DescribeStacksOutput.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,9 @@ private function populateResultCapabilities(\SimpleXMLElement $xml): array
115115
{
116116
$items = [];
117117
foreach ($xml->member as $item) {
118-
$items[] = (string) $item;
118+
$a = (string) $item;
119+
/** @var Capability::* $a */
120+
$items[] = $a;
119121
}
120122

121123
return $items;

src/Service/CodeBuild/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## NOT RELEASED
44

5+
### Changed
6+
7+
- Add DocBlock on array's items to help avoid psalm exceptions
8+
59
## 2.11.0
610

711
### Added

0 commit comments

Comments
 (0)