Skip to content

Commit 6cb7dfa

Browse files
committed
Help psalm to detect enum varaiables and avoid the More/LessSpecificReturn exceptions
1 parent d24d4db commit 6cb7dfa

39 files changed

+127
-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
@@ -315,6 +315,7 @@ private function parseResponseList(ListShape $shape, string $input, bool $requir
315315
if (!isset($this->generatedFunctions[$functionName])) {
316316
// prevent recursion
317317
$this->generatedFunctions[$functionName] = true;
318+
$docBloc = '';
318319

319320
if ($shapeMember->getShape() instanceof StructureShape || $shapeMember->getShape() instanceof ListShape || $shapeMember->getShape() instanceof MapShape) {
320321
$listAccessorRequired = true;
@@ -326,10 +327,17 @@ private function parseResponseList(ListShape $shape, string $input, bool $requir
326327
327328
return $items;';
328329
} else {
330+
if (!empty($shapeMember->getShape()->getEnum())) {
331+
$className = $this->namespaceRegistry->getEnum($shapeMember->getShape());
332+
$docBloc = '/** @var null|'.$className->getName().'::* $a */';
333+
$this->imports[] = $className;
334+
}
335+
329336
$listAccessorRequired = false;
330337
$body = '
331338
$items = [];
332339
foreach (INPUT_PROPERTY as $item) {
340+
DOC_BLOC
333341
$a = LIST_ACCESSOR;
334342
if (null !== $a) {
335343
$items[] = $a;
@@ -342,6 +350,7 @@ private function parseResponseList(ListShape $shape, string $input, bool $requir
342350
$this->functions[$functionName] = $this->createPopulateMethod($functionName, strtr($body, [
343351
'LIST_ACCESSOR' => $this->parseElement('$item', $shapeMember->getShape(), $listAccessorRequired, $inObject),
344352
'INPUT_PROPERTY' => $shape->isFlattened() ? '$json' : '$json' . ($shapeMember->getLocationName() ? '->' . $shapeMember->getLocationName() : ''),
353+
'DOC_BLOC' => $docBloc,
345354
]), $shape);
346355
}
347356

@@ -362,31 +371,42 @@ private function parseResponseMap(MapShape $shape, string $input, bool $required
362371
$this->generatedFunctions[$functionName] = true;
363372

364373
if (null === $locationName = $shape->getKey()->getLocationName()) {
374+
$docBloc = '';
375+
if (!empty($shape->getKey()->getShape()->getEnum())) {
376+
$className = $this->namespaceRegistry->getEnum($shape->getKey()->getShape());
377+
$docBloc = '/** @var '.$className->getName().'::* $name */';
378+
$this->imports[] = $className;
379+
}
380+
365381
// We need to use array keys
366382
if ($shapeValue->getShape() instanceof StructureShape) {
367383
$body = '
368384
$items = [];
369385
foreach ($json as $name => $value) {
386+
DOC_BLOC
370387
$items[(string) $name] = BUILDER_CODE;
371388
}
372389
373390
return $items;
374391
';
375392

376393
$this->functions[$functionName] = $this->createPopulateMethod($functionName, strtr($body, [
394+
'DOC_BLOC' => $docBloc,
377395
'BUILDER_CODE' => $this->parseResponseStructure($shapeValue->getShape(), '$value', true),
378396
]), $shape);
379397
} else {
380398
$body = '
381399
$items = [];
382400
foreach ($json as $name => $value) {
401+
DOC_BLOC
383402
$items[(string) $name] = CODE;
384403
}
385404
386405
return $items;
387406
';
388407

389408
$this->functions[$functionName] = $this->createPopulateMethod($functionName, strtr($body, [
409+
'DOC_BLOC' => $docBloc,
390410
'CODE' => $this->parseElement('$value', $shapeValue->getShape(), true, $inObject),
391411
]), $shape);
392412
}

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

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -325,19 +325,37 @@ private function parseXmlResponseList(ListShape $shape, string $input, bool $req
325325
';
326326
} else {
327327
$listAccessorRequired = true;
328-
$body = '
329-
$items = [];
330-
foreach (INPUT_PROPERTY as $item) {
331-
$items[] = LIST_ACCESSOR;
332-
}
333328

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

338355
$this->functions[$functionName] = $this->createPopulateMethod($functionName, strtr($body, [
339356
'LIST_ACCESSOR' => $this->parseXmlElement('$item', $shapeMember->getShape(), $listAccessorRequired, $inObject),
340357
'INPUT_PROPERTY' => $shape->isFlattened() ? '$xml' : ('$xml->' . ($shapeMember->getLocationName() ? $shapeMember->getLocationName() : 'member')),
358+
'ENUM_NAME' => $this->namespaceRegistry->getEnum($shapeMember->getShape())->getName(),
341359
]), $shape);
342360
}
343361

src/Service/CloudFormation/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
### Changed
66

77
- AWS enhancement: Documentation updates.
8+
- Add DocBlock on array's items to help avoid psalm exceptions
89

910
## 1.9.0
1011

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)