Skip to content

Commit 9302973

Browse files
authored
Add strict comparison null !== instead of ! (#1794)
1 parent 16bbf63 commit 9302973

File tree

2 files changed

+103
-78
lines changed

2 files changed

+103
-78
lines changed

src/Generator/PaginationGenerator.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,9 @@ private function generateOutputPaginationLoader(string $iterator, string $common
207207
if (!$moreResult) {
208208
$moreCondition = '';
209209
foreach ($outputToken as $property) {
210-
$moreCondition .= $this->generateGetter('$page', $property, (bool) $common);
210+
$moreCondition .= 'null !== ' . $this->generateGetter('$page', $property, (bool) $common);
211+
212+
break;
211213
}
212214
} else {
213215
$moreCondition = $this->generateGetter('$page', $moreResult, (bool) $common);

src/Generator/ResponseParser/RestXmlParser.php

Lines changed: 100 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ class RestXmlParser implements Parser
5050
*/
5151
private $imports = [];
5252

53+
/**
54+
* @var array<string, true>
55+
*/
56+
private $generatedFunctions = [];
57+
5358
public function __construct(NamespaceRegistry $namespaceRegistry, RequirementsRegistry $requirementsRegistry, TypeGenerator $typeGenerator)
5459
{
5560
$this->namespaceRegistry = $namespaceRegistry;
@@ -61,6 +66,7 @@ public function generate(StructureShape $shape, bool $throwOnError = true): Pars
6166
{
6267
$properties = [];
6368
$this->functions = [];
69+
$this->generatedFunctions = [];
6470
$this->imports = [];
6571
if (null !== $payload = $shape->getPayload()) {
6672
$member = $shape->getMember($payload);
@@ -80,19 +86,10 @@ public function generate(StructureShape $shape, bool $throwOnError = true): Pars
8086
continue;
8187
}
8288

83-
if (!$member->isNullable() && !$member->isRequired()) {
84-
$properties[] = strtr('if (null !== $v = (PROPERTY_ACCESSOR)) {
85-
$this->PROPERTY_NAME = $v;
86-
}', [
87-
'PROPERTY_NAME' => GeneratorHelper::normalizeName($member->getName()),
88-
'PROPERTY_ACCESSOR' => $this->parseXmlElement($this->getInputAccessor('$data', $member), $member->getShape(), $member->isRequired(), false),
89-
]);
90-
} else {
91-
$properties[] = strtr('$this->PROPERTY_NAME = PROPERTY_ACCESSOR;', [
92-
'PROPERTY_NAME' => GeneratorHelper::normalizeName($member->getName()),
93-
'PROPERTY_ACCESSOR' => $this->parseXmlElement($this->getInputAccessor('$data', $member), $member->getShape(), $member->isRequired(), false),
94-
]);
95-
}
89+
$properties[] = strtr('$this->PROPERTY_NAME = PROPERTY_ACCESSOR;', [
90+
'PROPERTY_NAME' => GeneratorHelper::normalizeName($member->getName()),
91+
'PROPERTY_ACCESSOR' => $this->parseXmlElement($this->getInputAccessor('$data', $member), $member->getShape(), $member->isRequired(), false),
92+
]);
9693
}
9794
}
9895

@@ -204,20 +201,35 @@ private function parseXmlElement(string $input, Shape $shape, bool $required, bo
204201

205202
private function parseXmlResponseStructure(StructureShape $shape, string $input, bool $required): string
206203
{
207-
$properties = [];
208-
foreach ($shape->getMembers() as $member) {
209-
$properties[] = strtr('PROPERTY_NAME => PROPERTY_ACCESSOR,', [
210-
'PROPERTY_NAME' => var_export($member->getName(), true),
211-
'PROPERTY_ACCESSOR' => $this->parseXmlElement($this->getInputAccessor($input, $member), $member->getShape(), $member->isRequired(), true),
212-
]);
204+
$functionName = 'populateResult' . ucfirst($shape->getName());
205+
if (!isset($this->generatedFunctions[$functionName])) {
206+
// prevent recursion
207+
$this->generatedFunctions[$functionName] = true;
208+
209+
$properties = [];
210+
foreach ($shape->getMembers() as $member) {
211+
$properties[] = strtr('PROPERTY_NAME => PROPERTY_ACCESSOR,', [
212+
'PROPERTY_NAME' => var_export($member->getName(), true),
213+
'PROPERTY_ACCESSOR' => $this->parseXmlElement($this->getInputAccessor('$xml', $member), $member->getShape(), $member->isRequired(), true),
214+
]);
215+
}
216+
217+
$body = 'return new CLASS_NAME([
218+
PROPERTIES
219+
]);';
220+
221+
$className = $this->namespaceRegistry->getObject($shape);
222+
$this->imports[] = $className;
223+
224+
$this->functions[$functionName] = $this->createPopulateMethod($functionName, strtr($body, [
225+
'CLASS_NAME' => $className->getName(),
226+
'PROPERTIES' => implode("\n", $properties),
227+
]), $shape);
213228
}
214229

215-
return strtr('REQUIRED new CLASS_NAME([
216-
PROPERTIES
217-
])', [
218-
'REQUIRED' => $required ? '' : '!' . $input . ' ? null : ',
219-
'CLASS_NAME' => $this->namespaceRegistry->getObject($shape)->getName(),
220-
'PROPERTIES' => implode("\n", $properties),
230+
return strtr($required ? '$this->FUNCTION_NAME(INPUT)' : '0 === INPUT->count() ? null : $this->FUNCTION_NAME(INPUT)', [
231+
'INPUT' => $input,
232+
'FUNCTION_NAME' => $functionName,
221233
]);
222234
}
223235

@@ -227,7 +239,7 @@ private function parseXmlResponseString(string $input, bool $required): string
227239
return strtr('(string) INPUT', ['INPUT' => $input]);
228240
}
229241

230-
return strtr('($v = INPUT) ? (string) $v : null', ['INPUT' => $input]);
242+
return strtr('(null !== $v = INPUT[0]) ? (string) $v : null', ['INPUT' => $input]);
231243
}
232244

233245
private function parseXmlResponseInteger(string $input, bool $required): string
@@ -236,7 +248,7 @@ private function parseXmlResponseInteger(string $input, bool $required): string
236248
return strtr('(int) (string) INPUT', ['INPUT' => $input]);
237249
}
238250

239-
return strtr('($v = INPUT) ? (int) (string) $v : null', ['INPUT' => $input]);
251+
return strtr('(null !== $v = INPUT[0]) ? (int) (string) $v : null', ['INPUT' => $input]);
240252
}
241253

242254
private function parseXmlResponseFloat(string $input, bool $required): string
@@ -245,7 +257,7 @@ private function parseXmlResponseFloat(string $input, bool $required): string
245257
return strtr('(float) (string) INPUT', ['INPUT' => $input]);
246258
}
247259

248-
return strtr('($v = INPUT) ? (float) (string) $v : null', ['INPUT' => $input]);
260+
return strtr('(null !== $v = INPUT[0]) ? (float) (string) $v : null', ['INPUT' => $input]);
249261
}
250262

251263
private function parseXmlResponseBool(string $input, bool $required): string
@@ -256,7 +268,7 @@ private function parseXmlResponseBool(string $input, bool $required): string
256268
return strtr('filter_var((string) INPUT, FILTER_VALIDATE_BOOLEAN)', ['INPUT' => $input]);
257269
}
258270

259-
return strtr('($v = INPUT) ? filter_var((string) $v, FILTER_VALIDATE_BOOLEAN) : null', ['INPUT' => $input]);
271+
return strtr('(null !== $v = INPUT[0]) ? filter_var((string) $v, FILTER_VALIDATE_BOOLEAN) : null', ['INPUT' => $input]);
260272
}
261273

262274
private function parseXmlResponseBlob(string $input, bool $required): string
@@ -265,7 +277,7 @@ private function parseXmlResponseBlob(string $input, bool $required): string
265277
return strtr('base64_decode((string) INPUT)', ['INPUT' => $input]);
266278
}
267279

268-
return strtr('($v = INPUT) ? base64_decode((string) $v) : null', ['INPUT' => $input]);
280+
return strtr('(null !== $v = INPUT[0]) ? base64_decode((string) $v) : null', ['INPUT' => $input]);
269281
}
270282

271283
private function parseXmlResponseTimestamp(Shape $shape, string $input, bool $required): string
@@ -281,47 +293,52 @@ private function parseXmlResponseTimestamp(Shape $shape, string $input, bool $re
281293
}
282294

283295
if (!$required) {
284-
$body = '($v = INPUT) ? ' . strtr($body, ['INPUT' => '$v']) . ' : null';
296+
$body = '(null !== $v = INPUT[0]) ? ' . strtr($body, ['INPUT' => '$v']) . ' : null';
285297
}
286298

287299
return strtr($body, ['INPUT' => $input]);
288300
}
289301

290302
private function parseXmlResponseList(ListShape $shape, string $input, bool $required, bool $inObject): string
291303
{
292-
$shapeMember = $shape->getMember();
293-
if ($shapeMember->getShape() instanceof StructureShape) {
294-
$listAccessorRequired = true;
295-
$body = '
296-
$items = [];
297-
foreach (INPUT_PROPERTY as $item) {
298-
$items[] = LIST_ACCESSOR;
299-
}
304+
$functionName = 'populateResult' . ucfirst($shape->getName());
305+
if (!isset($this->generatedFunctions[$functionName])) {
306+
// prevent recursion
307+
$this->generatedFunctions[$functionName] = true;
308+
309+
$shapeMember = $shape->getMember();
310+
if ($shapeMember->getShape() instanceof ListShape || $shapeMember->getShape() instanceof MapShape) {
311+
$listAccessorRequired = false;
312+
$body = '
313+
$items = [];
314+
foreach (INPUT_PROPERTY as $item) {
315+
$a = LIST_ACCESSOR;
316+
if (null !== $a) {
317+
$items[] = $a;
318+
}
319+
}
300320
301-
return $items;
302-
';
303-
} else {
304-
$listAccessorRequired = false;
305-
$body = '
306-
$items = [];
307-
foreach (INPUT_PROPERTY as $item) {
308-
$a = LIST_ACCESSOR;
309-
if (null !== $a) {
310-
$items[] = $a;
321+
return $items;
322+
';
323+
} else {
324+
$listAccessorRequired = true;
325+
$body = '
326+
$items = [];
327+
foreach (INPUT_PROPERTY as $item) {
328+
$items[] = LIST_ACCESSOR;
311329
}
312-
}
313330
314-
return $items;
315-
';
316-
}
331+
return $items;
332+
';
333+
}
317334

318-
$functionName = 'populateResult' . ucfirst($shape->getName());
319-
$this->functions[$functionName] = $this->createPopulateMethod($functionName, strtr($body, [
320-
'LIST_ACCESSOR' => $this->parseXmlElement('$item', $shapeMember->getShape(), $listAccessorRequired, $inObject),
321-
'INPUT_PROPERTY' => $shape->isFlattened() ? '$xml' : ('$xml->' . ($shapeMember->getLocationName() ? $shapeMember->getLocationName() : 'member')),
322-
]), $shape);
335+
$this->functions[$functionName] = $this->createPopulateMethod($functionName, strtr($body, [
336+
'LIST_ACCESSOR' => $this->parseXmlElement('$item', $shapeMember->getShape(), $listAccessorRequired, $inObject),
337+
'INPUT_PROPERTY' => $shape->isFlattened() ? '$xml' : ('$xml->' . ($shapeMember->getLocationName() ? $shapeMember->getLocationName() : 'member')),
338+
]), $shape);
339+
}
323340

324-
return strtr($required ? '$this->FUNCTION_NAME(INPUT)' : '!INPUT ? EMPTY : $this->FUNCTION_NAME(INPUT)', [
341+
return strtr($required ? '$this->FUNCTION_NAME(INPUT)' : '(0 === ($v = INPUT)->count()) ? EMPTY : $this->FUNCTION_NAME($v)', [
325342
'EMPTY' => !$inObject ? '[]' : 'null',
326343
'INPUT' => $input,
327344
'FUNCTION_NAME' => $functionName,
@@ -330,26 +347,31 @@ private function parseXmlResponseList(ListShape $shape, string $input, bool $req
330347

331348
private function parseXmlResponseMap(MapShape $shape, string $input, bool $required, bool $inObject): string
332349
{
333-
$shapeValue = $shape->getValue();
334-
$body = '
335-
$items = [];
336-
foreach (INPUT as $item) {
337-
$a = $item->MAP_VALUE;
338-
$items[$item->MAP_KEY->__toString()] = MAP_ACCESSOR;
339-
}
350+
$functionName = 'populateResult' . ucfirst($shape->getName());
351+
if (!isset($this->generatedFunctions[$functionName])) {
352+
// prevent recursion
353+
$this->generatedFunctions[$functionName] = true;
340354

341-
return $items;
342-
';
355+
$shapeValue = $shape->getValue();
356+
$body = '
357+
$items = [];
358+
foreach (INPUT as $item) {
359+
$a = $item->MAP_VALUE;
360+
$items[$item->MAP_KEY->__toString()] = MAP_ACCESSOR;
361+
}
343362
344-
$functionName = 'populateResult' . ucfirst($shape->getName());
345-
$this->functions[$functionName] = $this->createPopulateMethod($functionName, strtr($body, [
346-
'INPUT' => $shape->isFlattened() ? '$xml' : '$xml->entry',
347-
'MAP_KEY' => $shape->getKey()->getLocationName() ?? 'key',
348-
'MAP_VALUE' => $shape->getValue()->getLocationName() ?? 'value',
349-
'MAP_ACCESSOR' => $this->parseXmlElement('$a', $shapeValue->getShape(), true, $inObject),
350-
]), $shape);
351-
352-
return strtr($required ? '$this->FUNCTION_NAME(INPUT)' : '!INPUT ? EMPTY : $this->FUNCTION_NAME(INPUT)', [
363+
return $items;
364+
';
365+
366+
$this->functions[$functionName] = $this->createPopulateMethod($functionName, strtr($body, [
367+
'INPUT' => $shape->isFlattened() ? '$xml' : '$xml->entry',
368+
'MAP_KEY' => $shape->getKey()->getLocationName() ?? 'key',
369+
'MAP_VALUE' => $shape->getValue()->getLocationName() ?? 'value',
370+
'MAP_ACCESSOR' => $this->parseXmlElement('$a', $shapeValue->getShape(), true, $inObject),
371+
]), $shape);
372+
}
373+
374+
return strtr($required ? '$this->FUNCTION_NAME(INPUT)' : '(0 === ($v = INPUT)->count()) ? EMPTY : $this->FUNCTION_NAME($v)', [
353375
'EMPTY' => !$inObject ? '[]' : 'null',
354376
'INPUT' => $input,
355377
'FUNCTION_NAME' => $functionName,
@@ -368,6 +390,7 @@ private function createPopulateMethod(string $functionName, string $body, Shape
368390

369391
[$returnType, $parameterType, $memberClassNames] = $this->typeGenerator->getPhpType($shape);
370392
$method
393+
->setReturnType($returnType)
371394
->setComment('@return ' . $parameterType);
372395
$this->imports = array_merge($this->imports, $memberClassNames);
373396

0 commit comments

Comments
 (0)