Skip to content

Commit 32ace9f

Browse files
committed
Resolve reference type - Close #33
1 parent 29f9ee3 commit 32ace9f

File tree

2 files changed

+63
-17
lines changed

2 files changed

+63
-17
lines changed

src/ValueObject/ArrayFactory.php

Lines changed: 61 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,14 @@
1717
use OpenCodeModeling\CodeAst\Code\ParameterGenerator;
1818
use OpenCodeModeling\CodeAst\NodeVisitor\ClassMethod;
1919
use OpenCodeModeling\JsonSchemaToPhp\Type\ArrayType;
20+
use OpenCodeModeling\JsonSchemaToPhp\Type\BooleanType;
21+
use OpenCodeModeling\JsonSchemaToPhp\Type\IntegerType;
22+
use OpenCodeModeling\JsonSchemaToPhp\Type\NumberType;
23+
use OpenCodeModeling\JsonSchemaToPhp\Type\ObjectType;
2024
use OpenCodeModeling\JsonSchemaToPhp\Type\ReferenceType;
2125
use OpenCodeModeling\JsonSchemaToPhp\Type\ScalarType;
26+
use OpenCodeModeling\JsonSchemaToPhp\Type\StringType;
27+
use OpenCodeModeling\JsonSchemaToPhp\Type\TypeDefinition;
2228
use OpenCodeModeling\JsonSchemaToPhp\Type\TypeSet;
2329
use OpenCodeModeling\JsonSchemaToPhpAst\Common\IteratorFactory;
2430
use PhpParser\NodeVisitor;
@@ -199,7 +205,7 @@ public function classBuilder(ArrayType $typeDefinition): ClassBuilder
199205
return $this->classBuilderFromNative($name, ...$typeDefinition->items());
200206
}
201207

202-
private function determineTypeName(string $name, TypeSet ...$typeSets): ?string
208+
private function determineType(string $name, TypeSet ...$typeSets): ?TypeDefinition
203209
{
204210
if (\count($typeSets) !== 1) {
205211
throw new \RuntimeException('Can only handle one JSON type');
@@ -217,7 +223,7 @@ private function determineTypeName(string $name, TypeSet ...$typeSets): ?string
217223
$resolvedTypeSet = $type->resolvedType();
218224

219225
if ($resolvedTypeSet === null) {
220-
return $type->extractNameFromReference();
226+
return $type;
221227
}
222228
if (\count($resolvedTypeSet) !== 1) {
223229
throw new \RuntimeException('Can only handle one JSON type');
@@ -232,7 +238,25 @@ private function determineTypeName(string $name, TypeSet ...$typeSets): ?string
232238
);
233239
}
234240

235-
return $type->name();
241+
return $type;
242+
}
243+
244+
private function determineTypeMethod(TypeDefinition $type): string
245+
{
246+
switch (true) {
247+
case $type instanceof ArrayType:
248+
case $type instanceof ObjectType:
249+
return 'Array';
250+
case $type instanceof BooleanType:
251+
return 'Bool';
252+
case $type instanceof IntegerType:
253+
return 'Int';
254+
case $type instanceof NumberType:
255+
return 'Float';
256+
case $type instanceof StringType:
257+
default:
258+
return 'String';
259+
}
236260
}
237261

238262
/**
@@ -242,14 +266,24 @@ private function determineTypeName(string $name, TypeSet ...$typeSets): ?string
242266
*/
243267
public function nodeVisitorsFromNative(string $name, TypeSet ...$typeSets): array
244268
{
245-
$typeName = $this->determineTypeName($name, ...$typeSets);
269+
$type = $this->determineType($name, ...$typeSets);
270+
271+
if ($type === null) {
272+
throw new \RuntimeException('Could not determine JSON schema type');
273+
}
274+
$typeName = $type->name();
275+
276+
if ($type instanceof ReferenceType) {
277+
$typeName = $type->extractNameFromReference();
278+
}
279+
$typeMethod = $this->determineTypeMethod($type);
246280

247281
$nodeVisitors = $this->iteratorFactory->nodeVisitorsFromNative(
248282
($this->propertyNameFilter)($name),
249283
($this->classNameFilter)($typeName)
250284
);
251285

252-
$nodeVisitors[] = new ClassMethod($this->methodFromArray($name, $typeName));
286+
$nodeVisitors[] = new ClassMethod($this->methodFromArray($name, $typeName, 'from' . $typeMethod));
253287
$nodeVisitors[] = new ClassMethod($this->methodFromItems($name, $typeName));
254288
$nodeVisitors[] = new ClassMethod($this->methodEmptyList());
255289
$nodeVisitors[] = new ClassMethod($this->methodMagicConstruct($name, $name, $typeName));
@@ -260,22 +294,32 @@ public function nodeVisitorsFromNative(string $name, TypeSet ...$typeSets): arra
260294
$nodeVisitors[] = new ClassMethod($this->methodContains($name, $typeName));
261295
$nodeVisitors[] = new ClassMethod($this->methodFilter($name));
262296
$nodeVisitors[] = new ClassMethod($this->methodItems($name, $typeName));
263-
$nodeVisitors[] = new ClassMethod($this->methodToArray($name, $typeName));
297+
$nodeVisitors[] = new ClassMethod($this->methodToArray($name, $typeName, 'to' . $typeMethod));
264298
$nodeVisitors[] = new ClassMethod($this->methodEquals());
265299

266300
return $nodeVisitors;
267301
}
268302

269303
public function classBuilderFromNative(string $name, TypeSet ...$typeSets): ClassBuilder
270304
{
271-
$typeName = $this->determineTypeName($name, ...$typeSets);
305+
$type = $this->determineType($name, ...$typeSets);
306+
307+
if ($type === null) {
308+
throw new \RuntimeException('Could not determine JSON schema type');
309+
}
310+
$typeName = $type->name();
311+
312+
if ($type instanceof ReferenceType) {
313+
$typeName = $type->extractNameFromReference();
314+
}
315+
$typeMethod = $this->determineTypeMethod($type);
272316

273317
$classBuilder = $this->iteratorFactory->classBuilderFromNative(
274318
($this->propertyNameFilter)($name),
275319
($this->classNameFilter)($typeName)
276320
);
277321
$classBuilder->addMethod(
278-
ClassMethodBuilder::fromNode($this->methodFromArray($name, $typeName)->generate()),
322+
ClassMethodBuilder::fromNode($this->methodFromArray($name, $typeName, 'from' . $typeMethod)->generate()),
279323
ClassMethodBuilder::fromNode($this->methodFromItems($name, $typeName)->generate()),
280324
ClassMethodBuilder::fromNode($this->methodEmptyList()->generate()),
281325
ClassMethodBuilder::fromNode($this->methodMagicConstruct($name, $name, $typeName)->generate()),
@@ -286,7 +330,7 @@ public function classBuilderFromNative(string $name, TypeSet ...$typeSets): Clas
286330
ClassMethodBuilder::fromNode($this->methodContains($name, $typeName)->generate()),
287331
ClassMethodBuilder::fromNode($this->methodFilter($name)->generate()),
288332
ClassMethodBuilder::fromNode($this->methodItems($name, $typeName)->generate()),
289-
ClassMethodBuilder::fromNode($this->methodToArray($name, $typeName)->generate()),
333+
ClassMethodBuilder::fromNode($this->methodToArray($name, $typeName, 'to' . $typeMethod)->generate()),
290334
ClassMethodBuilder::fromNode($this->methodEquals()->generate()),
291335
);
292336

@@ -518,11 +562,12 @@ public function methodItems(
518562

519563
public function methodToArray(
520564
string $propertyName,
521-
string $argumentType
565+
string $argumentType,
566+
string $typeMethod = 'toString'
522567
): MethodGenerator {
523568
$body = <<<'PHP'
524569
return \array_map(static function (%s $%s) {
525-
return $%s->toString();
570+
return $%s->%s();
526571
}, $this->%s);
527572
PHP;
528573

@@ -534,7 +579,7 @@ public function methodToArray(
534579
'toArray',
535580
[],
536581
MethodGenerator::FLAG_PUBLIC,
537-
new BodyGenerator($this->parser, \sprintf($body, $argumentType, $argumentTypeVarName, $argumentTypeVarName, $propertyName))
582+
new BodyGenerator($this->parser, \sprintf($body, $argumentType, $argumentTypeVarName, $argumentTypeVarName, $typeMethod, $propertyName))
538583
);
539584
$method->setTyped($this->typed);
540585
$method->setReturnType('array');
@@ -544,11 +589,12 @@ public function methodToArray(
544589

545590
public function methodFromArray(
546591
string $argumentName,
547-
string $typeName
592+
string $typeName,
593+
string $typeMethod = 'fromString'
548594
): MethodGenerator {
549595
$body = <<<'PHP'
550596
return new self(...array_map(static function (string $item) {
551-
return %s::fromString($item);
597+
return %s::%s($item);
552598
}, $%s));
553599
PHP;
554600
$argumentName = ($this->propertyNameFilter)($argumentName);
@@ -560,7 +606,7 @@ public function methodFromArray(
560606
new ParameterGenerator($argumentName, 'array'),
561607
],
562608
MethodGenerator::FLAG_PUBLIC | MethodGenerator::FLAG_STATIC,
563-
new BodyGenerator($this->parser, \sprintf($body, $typeName, $argumentName))
609+
new BodyGenerator($this->parser, \sprintf($body, $typeName, $typeMethod, $argumentName))
564610
);
565611
$method->setTyped($this->typed);
566612
$method->setReturnType('self');

tests/ValueObjectFactoryTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ public function count() : int
502502
public static function fromArray(array $shippingAddresses) : self
503503
{
504504
return new self(...array_map(static function (string $item) {
505-
return Address::fromString($item);
505+
return Address::fromArray($item);
506506
}, $shippingAddresses));
507507
}
508508
public static function fromItems(Address ...$shippingAddresses) : self
@@ -567,7 +567,7 @@ public function items() : array
567567
public function toArray() : array
568568
{
569569
return \array_map(static function (Address $address) {
570-
return $address->toString();
570+
return $address->toArray();
571571
}, $this->shippingAddresses);
572572
}
573573
/**

0 commit comments

Comments
 (0)