Skip to content

Commit

Permalink
Port discriminator feature from 4.x branch to master (#91)
Browse files Browse the repository at this point in the history
Port discriminator feature from 4.x branch to master
  • Loading branch information
Korbeil committed Jun 19, 2019
2 parents b859e7c + f499b15 commit a4e67df
Show file tree
Hide file tree
Showing 54 changed files with 1,026 additions and 73 deletions.
53 changes: 35 additions & 18 deletions src/JsonSchema/Generator/Model/GetterSetterGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,29 @@ protected function createGetter(Property $property, string $namespace, bool $req
);
}

protected function createSetter(Property $property, string $namespace, bool $required): Stmt\ClassMethod
protected function createSetter(Property $property, string $namespace, bool $required, bool $fluent = true): Stmt\ClassMethod
{
$setType = $property->getType()->getTypeHint($namespace);

if ($setType && !$required) {
$setType = '?' . $setType;
}

$stmts = [
// $this->property = $property;
new Stmt\Expression(new Expr\Assign(
new Expr\PropertyFetch(
new Expr\Variable('this'),
$this->getNaming()->getPropertyName($property->getPhpName())
), new Expr\Variable($this->getNaming()->getPropertyName($property->getPhpName()))
)),
];

if ($fluent) {
// return $this;
$stmts[] = new Stmt\Return_(new Expr\Variable('this'));
}

return new Stmt\ClassMethod(
// setProperty
$this->getNaming()->getPrefixedMethodName('set', $property->getPhpName()),
Expand All @@ -65,20 +80,10 @@ protected function createSetter(Property $property, string $namespace, bool $req
'params' => [
new Param(new Expr\Variable($this->getNaming()->getPropertyName($property->getPhpName())), null, $setType),
],
'stmts' => [
// $this->property = $property;
new Stmt\Expression(new Expr\Assign(
new Expr\PropertyFetch(
new Expr\Variable('this'),
$this->getNaming()->getPropertyName($property->getPhpName())
), new Expr\Variable($this->getNaming()->getPropertyName($property->getPhpName()))
)),
// return $this;
new Stmt\Return_(new Expr\Variable('this')),
],
'returnType' => 'self',
'stmts' => $stmts,
'returnType' => $fluent ? 'self' : null,
], [
'comments' => [$this->createSetterDoc($property, $namespace, $required)],
'comments' => [$this->createSetterDoc($property, $namespace, $required, $fluent)],
]
);
}
Expand All @@ -95,18 +100,30 @@ protected function createGetterDoc(Property $property, string $namespace, bool $
, $property->getDescription(), $this->getDocType($property, $namespace, $required)));
}

protected function createSetterDoc(Property $property, string $namespace, bool $required): Doc
protected function createSetterDoc(Property $property, string $namespace, bool $required, bool $fluent): Doc
{
return new Doc(sprintf(<<<EOD
$description = sprintf(<<<EOD
/**
* %s
*
* @param %s %s
EOD
, $property->getDescription(), $this->getDocType($property, $namespace, $required), '$' . $property->getPhpName());

if ($fluent) {
$description .= <<<EOD
*
* @return self
EOD;
}

$description .= <<<EOD
*/
EOD
, $property->getDescription(), $this->getDocType($property, $namespace, $required), '$' . $property->getPhpName()));
EOD;

return new Doc($description);
}

private function getDocType(Property $property, string $namespace, bool $required): string
Expand Down
31 changes: 23 additions & 8 deletions src/JsonSchema/Generator/ModelGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
use Jane\JsonSchema\Generator\Model\ClassGenerator;
use Jane\JsonSchema\Generator\Model\GetterSetterGenerator;
use Jane\JsonSchema\Generator\Model\PropertyGenerator;
use Jane\JsonSchema\Guesser\Guess\ClassGuess;
use Jane\JsonSchema\Guesser\Guess\Property;
use Jane\JsonSchema\Schema;
use PhpParser\Node\Name;
use PhpParser\Node\Stmt;
Expand Down Expand Up @@ -53,20 +55,33 @@ public function generate(Schema $schema, string $className, Context $context)
foreach ($class->getProperties() as $property) {
$required = !$property->isNullable() && $context->isStrict();
$properties[] = $this->createProperty($property, $schema->getNamespace() . '\\Model');
$methods[] = $this->createGetter($property, $schema->getNamespace() . '\\Model', $required);
$methods[] = $this->createSetter($property, $schema->getNamespace() . '\\Model', $required);
$methods = array_merge($methods, $this->doCreateClassMethods($class, $property, $schema->getNamespace() . '\\Model', $required));
}

$model = $this->createModel(
$class->getName(),
$properties,
$methods,
\count($class->getExtensionsType()) > 0
);
$model = $this->doCreateModel($class, $properties, $methods);

$namespace = new Stmt\Namespace_(new Name($schema->getNamespace() . '\\Model'), [$model]);

$schema->addFile(new File($schema->getDirectory() . '/Model/' . $class->getName() . '.php', $namespace, self::FILE_TYPE_MODEL));
}
}

protected function doCreateClassMethods(ClassGuess $classGuess, Property $property, string $namespace, bool $required)
{
$methods = [];
$methods[] = $this->createGetter($property, $namespace, $required);
$methods[] = $this->createSetter($property, $namespace, $required);

return $methods;
}

protected function doCreateModel(ClassGuess $class, $properties, $methods): Stmt\Class_
{
return $this->createModel(
$class->getName(),
$properties,
$methods,
\count($class->getExtensionsType()) > 0
);
}
}
29 changes: 18 additions & 11 deletions src/JsonSchema/Generator/Normalizer/DenormalizerGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,17 +67,7 @@ protected function createDenormalizeMethod(string $modelFqdn, Context $context,
];
}

array_unshift($statements, new Stmt\If_(
new Expr\BooleanNot(new Expr\FuncCall(new Name('is_object'), [new Arg(new Expr\Variable('data'))])),
[
'stmts' => [
$context->isStrict() ?
new Stmt\Throw_(new Expr\New_(new Name('InvalidArgumentException')))
:
new Stmt\Return_(new Expr\ConstFetch(new Name('null'))),
],
]
));
array_unshift($statements, ...$this->denormalizeMethodStatements($classGuess, $context));

$unset = \count($classGuess->getExtensionsType()) > 0;

Expand Down Expand Up @@ -159,4 +149,21 @@ protected function createDenormalizeMethod(string $modelFqdn, Context $context,
'stmts' => $statements,
]);
}

protected function denormalizeMethodStatements(ClassGuess $classGuess, Context $context): array
{
return [
new Stmt\If_(
new Expr\BooleanNot(new Expr\FuncCall(new Name('is_object'), [new Arg(new Expr\Variable('data'))])),
[
'stmts' => [
$context->isStrict() ?
new Stmt\Throw_(new Expr\New_(new Name('InvalidArgumentException')))
:
new Stmt\Return_(new Expr\ConstFetch(new Name('null'))),
],
]
),
];
}
}
11 changes: 8 additions & 3 deletions src/JsonSchema/Generator/Normalizer/NormalizerGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,7 @@ protected function createNormalizeMethod($modelFqdn, Context $context, ClassGues
{
$context->refreshScope();
$dataVariable = new Expr\Variable('data');
$statements = [
new Stmt\Expression(new Expr\Assign($dataVariable, new Expr\New_(new Name('\\stdClass')))),
];
$statements = $this->normalizeMethodStatements($dataVariable, $classGuess, $context);

/** @var Property $property */
foreach ($classGuess->getProperties() as $property) {
Expand Down Expand Up @@ -140,4 +138,11 @@ protected function createNormalizeMethod($modelFqdn, Context $context, ClassGues
'stmts' => $statements,
]);
}

protected function normalizeMethodStatements(Expr\Variable $dataVariable, ClassGuess $classGuess, Context $context): array
{
return [
new Stmt\Expression(new Expr\Assign($dataVariable, new Expr\New_(new Name('\\stdClass')))),
];
}
}
2 changes: 1 addition & 1 deletion src/JsonSchema/Guesser/Guess/ClassGuess.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class ClassGuess
/**
* @var Property[]
*/
private $properties;
private $properties = [];

private $reference;

Expand Down
9 changes: 7 additions & 2 deletions src/JsonSchema/Guesser/JsonSchema/AllOfGuesser.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class AllOfGuesser implements GuesserInterface, TypeGuesserInterface, ChainGuess
use ChainGuesserAwareTrait;
use GuesserResolverTrait;

private $naming;
protected $naming;

public function __construct(SerializerInterface $serializer, Naming $naming)
{
Expand Down Expand Up @@ -69,7 +69,7 @@ public function guessClass($object, $name, $reference, Registry $registry)
}
}

$registry->getSchema($reference)->addClass($reference, new ClassGuess($object, $reference, $this->naming->getClassName($name), $extensions));
$registry->getSchema($reference)->addClass($reference, $this->createClassGuess($object, $reference, $name, $extensions));
}

foreach ($object->getAllOf() as $allOfIndex => $allOf) {
Expand Down Expand Up @@ -168,4 +168,9 @@ protected function getSchemaClass()
{
return JsonSchema::class;
}

protected function createClassGuess($object, $reference, $name, $extensions): ClassGuess
{
return new ClassGuess($object, $reference, $this->naming->getClassName($name), $extensions);
}
}
7 changes: 6 additions & 1 deletion src/JsonSchema/Guesser/JsonSchema/ObjectGuesser.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public function guessClass($object, $name, $reference, Registry $registry)
}
}

$registry->getSchema($reference)->addClass($reference, new ClassGuess($object, $reference, $this->naming->getClassName($name), $extensions));
$registry->getSchema($reference)->addClass($reference, $this->createClassGuess($object, $reference, $name, $extensions));
}

foreach ($object->getProperties() as $key => $property) {
Expand Down Expand Up @@ -150,4 +150,9 @@ protected function getSchemaClass()
{
return JsonSchema::class;
}

protected function createClassGuess($object, $reference, $name, $extensions): ClassGuess
{
return new ClassGuess($object, $reference, $this->naming->getClassName($name), $extensions);
}
}
44 changes: 44 additions & 0 deletions src/OpenApi/Generator/Model/ClassGenerator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

namespace Jane\OpenApi\Generator\Model;

use Jane\JsonSchema\Generator\Model\ClassGenerator as BaseClassGenerator;
use PhpParser\Node;
use PhpParser\Node\Name;
use PhpParser\Node\Stmt;

trait ClassGenerator
{
use BaseClassGenerator {
createModel as baseCreateModel;
}

/**
* Return a model class.
*
* @param string $name
* @param Node[] $properties
* @param Node[] $methods
* @param bool $hasExtensions
* @param string $extends
*
* @return Stmt\Class_
*/
protected function createModel(string $name, $properties, $methods, bool $hasExtensions = false, $extends = null): Stmt\Class_
{
$classExtends = null;
if (null !== $extends) {
$classExtends = new Name($extends);
} elseif ($hasExtensions) {
$classExtends = new Name('\ArrayObject');
}

return new Stmt\Class_(
new Name($this->getNaming()->getClassName($name)),
[
'stmts' => array_merge($properties, $methods),
'extends' => $classExtends,
]
);
}
}
44 changes: 44 additions & 0 deletions src/OpenApi/Generator/ModelGenerator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

namespace Jane\OpenApi\Generator;

use Jane\JsonSchema\Generator\ModelGenerator as BaseModelGenerator;
use Jane\JsonSchema\Guesser\Guess\ClassGuess as BaseClassGuess;
use Jane\JsonSchema\Guesser\Guess\Property;
use Jane\OpenApi\Generator\Model\ClassGenerator;
use Jane\OpenApi\Guesser\Guess\ClassGuess;
use Jane\OpenApi\Guesser\Guess\MultipleClass;
use PhpParser\Node\Stmt;

class ModelGenerator extends BaseModelGenerator
{
use ClassGenerator;

protected function doCreateClassMethods(BaseClassGuess $classGuess, Property $property, string $namespace, bool $required)
{
$methods = [];
$methods[] = $this->createGetter($property, $namespace, $required);
$methods[] = $this->createSetter($property, $namespace, $required, $classGuess instanceof MultipleClass ? false : true);

return $methods;
}

protected function doCreateModel(BaseClassGuess $class, $properties, $methods): Stmt\Class_
{
$extends = null;
if ($class instanceof ClassGuess &&
$class->getMultipleClass() instanceof MultipleClass) {
$extends = $this->getNaming()->getClassName($class->getMultipleClass()->getName());
}

$classModel = $this->createModel(
$class->getName(),
$properties,
$methods,
\count($class->getExtensionsType()) > 0,
$extends
);

return $classModel;
}
}
Loading

0 comments on commit a4e67df

Please sign in to comment.