Commit 1bbf195c authored by Guillaume Perréal's avatar Guillaume Perréal
Browse files

Corrections PHPStan.

parent 0ad6f764
includes:
- vendor/irstea/phpstan-config/strict.neon
parameters:
level: 7
paths:
- src/php
......@@ -22,6 +22,7 @@
namespace Irstea\NgModelGeneratorBundle\Command;
use ApiPlatform\Core\Documentation\Documentation;
use Assert\Assertion;
use Irstea\NgModelGeneratorBundle\ModelGenerator;
use Irstea\NgModelGeneratorBundle\Writers\ConsoleWriter;
use Irstea\NgModelGeneratorBundle\Writers\DirectoryWriter;
......@@ -91,6 +92,9 @@ final class NgModelGenerateCommand extends Command
if ($input->getOption('restrict')) {
$globs = $input->getOption('restrict');
Assertion::isArray($globs);
Assertion::allString($globs);
$writer = new FilteringFileWriter($writer, function (string $path) use ($globs): bool {
foreach ($globs as $glob) {
if (fnmatch($glob, $path, FNM_PATHNAME)) {
......@@ -118,14 +122,17 @@ final class NgModelGenerateCommand extends Command
private function openWriter(InputInterface $input, OutputInterface $output): MultiFileWriter
{
$zipPath = $input->getOption('zip');
Assertion::nullOrString($zipPath);
if ($zipPath) {
$archive = $this->openZipArchive($zipPath, $input->getOption('force'));
$force = (bool) $input->getOption('force');
$archive = $this->openZipArchive($zipPath, $force);
$output->write("Writing to ZIP archive: <info>$zipPath</info>\n");
return new ZipWriter($archive);
}
$dirPath = $input->getOption('output');
Assertion::nullOrString($dirPath);
if ($dirPath) {
$output->write("Writing to directory: <info>$dirPath</info>\n");
......
......@@ -22,8 +22,8 @@
namespace Irstea\NgModelGeneratorBundle\Command;
use ApiPlatform\Core\Documentation\Documentation;
use Assert\Assertion;
use Irstea\NgModelGeneratorBundle\Metadata\MetadataFactoryInterface;
use Irstea\NgModelGeneratorBundle\ModelGenerator;
use Irstea\NgModelGeneratorBundle\Models\PHPClass;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
......@@ -48,8 +48,8 @@ final class NgModelMetadataCommand extends Command
/**
* NgModelGenerateCommand constructor.
*
* @param ModelGenerator $generator
* @param Documentation $documentation
* @param MetadataFactoryInterface $metadataFactory
* @param Documentation $documentation
*/
public function __construct(
MetadataFactoryInterface $metadataFactory,
......@@ -78,6 +78,8 @@ final class NgModelMetadataCommand extends Command
protected function execute(InputInterface $input, OutputInterface $output)
{
$classes = $input->getArgument('classes');
Assertion::isArray($classes);
Assertion::allString($classes);
$metadata = [];
foreach ($this->documentation->getResourceNameCollection() as $className) {
......@@ -88,6 +90,8 @@ final class NgModelMetadataCommand extends Command
$metadata[$class->getBaseName()] = $this->metadataFactory->getResourceMetadata($class);
}
$output->writeln(\json_encode($metadata, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE));
$json = \json_encode($metadata, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE);
Assertion::string($json);
$output->writeln($json);
}
}
......@@ -57,7 +57,7 @@ class CallbackFilterRecursorIterator extends RecursorIterator
*
* @return \RecursiveIterator
*/
protected function doGetChildren(\Iterator $iter): \RecursiveIterator
protected function doGetChildren(\Traversable $iter): \RecursiveIterator
{
return new self($iter, $this->filter);
}
......
......@@ -97,7 +97,7 @@ final class IteratorBuilder implements \IteratorAggregate
}
/**
* @param callable $param
* @param callable $where
*
* @return IteratorBuilder
*/
......
......@@ -56,11 +56,11 @@ class RecursorIterator extends \IteratorIterator implements \RecursiveIterator
}
/**
* @param \Iterator $iter
* @param \Traversable $iter
*
* @return \RecursiveIterator
*/
protected function doGetChildren(\Iterator $iter): \RecursiveIterator
protected function doGetChildren(\Traversable $iter): \RecursiveIterator
{
return new self($iter);
}
......
......@@ -32,7 +32,7 @@ final class UniqueFilter
private $seen = [];
/**
* @param $value
* @param mixed $value
*
* @return bool
*/
......
......@@ -30,6 +30,7 @@ use ApiPlatform\Core\Metadata\Property\Factory\PropertyNameCollectionFactoryInte
use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
use ApiPlatform\Core\Metadata\Resource\ResourceMetadata as APIResourceMetadata;
use ApiPlatform\Core\PathResolver\OperationPathResolverInterface;
use Assert\Assertion;
use Doctrine\Common\Inflector\Inflector;
use Irstea\NgModelGeneratorBundle\Models\ClassName;
use Irstea\NgModelGeneratorBundle\Models\PHPClass;
......@@ -145,8 +146,7 @@ final class MetadataFactory implements MetadataFactoryInterface
return new ResourceMetadata(
$class,
$parentClass ? PHPClass::get($parentClass->getName()) : null,
$metadata->getShortName(),
$metadata->getDescription(),
$metadata->getDescription() ?: '',
$classMeta->isAbstract(),
$defaultNormalization,
$this->getOperations($class)
......@@ -194,8 +194,11 @@ final class MetadataFactory implements MetadataFactoryInterface
OperationType::ITEM => $resourceMetadata->getItemOperations(),
OperationType::COLLECTION => $resourceMetadata->getCollectionOperations(),
] as $type => $ops) {
if (!$ops) {
continue;
}
foreach ($ops as $name => $operation) {
$operations[] = $this->getOperation($class, $resourceMetadata, $name, $type, $operation);
$operations[] = $this->getOperation($class, $resourceMetadata, (string) $name, $type, $operation);
}
}
......@@ -224,22 +227,23 @@ final class MetadataFactory implements MetadataFactoryInterface
$method = $this->operationMethodResolver->getCollectionOperationMethod($class->getFullName(), $name);
}
$shortName = $resourceMetadata->getShortName();
Assertion::notNull($shortName);
/** @noinspection PhpMethodParametersCountMismatchInspection */
$path = $this->operationPathResolver->resolveOperationPath($resourceMetadata->getShortName(), $operation, $type, $name);
$path = $this->operationPathResolver->resolveOperationPath($shortName, $operation, $type);
// Suppression du suffixe de format, qui n'est pas utilisable en dehors de Symfony
$path = \str_replace('.{_format}', '', $path);
$getAttribute = function (string $attrName, $default) use ($resourceMetadata, $type, $name) {
return $resourceMetadata->getTypedOperationAttribute($type, $name, $attrName, $default, true);
};
if ($type === OperationType::COLLECTION && $method === 'GET') {
$filters = $this->getFilters($class, $getAttribute('filters', []));
$paginationEnabled = (bool)$getAttribute('pagination_enabled', true);
$paginationClientItemsPerPage = (bool)$getAttribute('pagination_client_items_per_page', true);
$paginationEnabled = (bool) $getAttribute('pagination_enabled', true);
$paginationClientItemsPerPage = (bool) $getAttribute('pagination_client_items_per_page', true);
$pagination = $this->buildPagination($paginationEnabled, $paginationClientItemsPerPage);
} else {
......@@ -396,8 +400,9 @@ final class MetadataFactory implements MetadataFactoryInterface
$properties[$propertyName] = $property;
if ($property->isEmbedded()) {
$type = $property->getLeafType();
if ($type->getClassName()) {
$queue[] = PHPClass::get($type->getClassName());
$className = $type->getClassName();
if ($className) {
$queue[] = PHPClass::get($className);
}
}
}
......
......@@ -21,6 +21,7 @@
namespace Irstea\NgModelGeneratorBundle\Metadata;
use Assert\Assertion;
use Irstea\NgModelGeneratorBundle\Models\HasName;
use Symfony\Component\PropertyInfo\Type;
......@@ -66,6 +67,7 @@ class PropertyMetadata implements \JsonSerializable, HasName
* @param string $description
* @param Type $type
* @param bool $identifier
* @param bool $nullable
* @param bool $readable
* @param bool $writable
* @param bool $initializable
......@@ -132,8 +134,9 @@ class PropertyMetadata implements \JsonSerializable, HasName
public function getLeafType(): Type
{
$type = $this->type;
while ($type && $type->isCollection() && $type->getCollectionValueType()) {
while ($type->isCollection() && $type->getCollectionValueType()) {
$type = $type->getCollectionValueType();
Assertion::notNull($type);
}
return $type;
......
......@@ -112,8 +112,8 @@ class PropertyMetadataFactory
$typeMeta,
$propertyMeta->isIdentifier() ?: false,
$nullable,
$propertyMeta->isReadable(),
$propertyMeta->isWritable(),
$propertyMeta->isReadable() ?: false,
$propertyMeta->isWritable() ?: false,
(bool) $propertyMeta->isInitializable(),
$link,
$embedded
......@@ -121,7 +121,7 @@ class PropertyMetadataFactory
}
/**
* @param $propertyMeta
* @param APIPropertyMetadata $propertyMeta
*
* @return array
*/
......@@ -211,9 +211,8 @@ class PropertyMetadataFactory
}
/**
* @param string $mode
* @param bool $isResource
* @param APIPropertyMetadata $propertyMeta
* @param mixed $isResource
*
* @return bool
*/
......@@ -228,10 +227,10 @@ class PropertyMetadataFactory
return $propertyMeta->isWritable() || $propertyMeta->isInitializable();
case self::MODE_READ:
return $propertyMeta->isReadable();
return $propertyMeta->isReadable() ?: false;
case self::MODE_UPDATE:
return $propertyMeta->isWritable();
return $propertyMeta->isWritable() ?: false;
default:
return $propertyMeta->isReadable() || $propertyMeta->isWritable();
......
......@@ -59,7 +59,7 @@ final class ResourceClassHierarchy implements ClassHierarchy
$reflClass = new \ReflectionClass($className);
$reflParent = $reflClass->getParentClass();
if (!$reflParent) {
$this->parents[$className] = null;
unset($this->parents[$className]);
return;
}
......
......@@ -51,7 +51,6 @@ class ResourceMetadata implements ClassName
*
* @param ClassName $class
* @param ClassName|null $parentClass
* @param string $shortName
* @param string $description
* @param bool $abstract
* @param SerializationMetadata $defaultNormalization
......@@ -60,7 +59,6 @@ class ResourceMetadata implements ClassName
public function __construct(
ClassName $class,
?ClassName $parentClass,
string $shortName,
string $description,
bool $abstract,
SerializationMetadata $defaultNormalization,
......
......@@ -40,7 +40,6 @@ use Irstea\NgModelGeneratorBundle\Models\Types\StringConst;
use Irstea\NgModelGeneratorBundle\Models\Types\Type;
use Irstea\NgModelGeneratorBundle\Models\Types\Union;
use Irstea\NgModelGeneratorBundle\Writers\MultiFileWriter;
use Irstea\NgModelGeneratorBundle\Writers\Writer;
use Symfony\Component\PropertyInfo\Type as PHPType;
use Twig\Environment;
......@@ -58,7 +57,7 @@ final class ModelGenerator
/** @var Documentation */
private $documentation;
/** @var TypeFactory */
/** @var TypeFactoryInterface */
private $typeFactory;
/** @var SerializationMapperFactoryInterface */
......@@ -82,8 +81,12 @@ final class ModelGenerator
* Génère les modèles Typescript.
* Cette méthode n'est pas réentrante.
*
* @param Documentation $doc
* @param Writer $writer
* @param Documentation $doc
* @param MultiFileWriter $writer
*
* @throws \Twig_Error_Loader
* @throws \Twig_Error_Runtime
* @throws \Twig_Error_Syntax
*/
public function generate(Documentation $doc, MultiFileWriter $writer): void
{
......@@ -108,8 +111,6 @@ final class ModelGenerator
* @throws \Twig_Error_Loader
* @throws \Twig_Error_Runtime
* @throws \Twig_Error_Syntax
*
* @return string
*/
private function doGenerate(MultiFileWriter $writer): void
{
......@@ -170,8 +171,6 @@ final class ModelGenerator
* @throws \Twig_Error_Loader
* @throws \Twig_Error_Runtime
* @throws \Twig_Error_Syntax
*
* @return string
*/
private function generateFile(MultiFileWriter $writer, string $path, array $context): void
{
......
......@@ -22,6 +22,7 @@
namespace Irstea\NgModelGeneratorBundle\Models;
use Irstea\NgModelGeneratorBundle\Exceptions\DomainException;
use Irstea\NgModelGeneratorBundle\Metadata\PropertyMetadata;
/**
* Class ClassInfo.
......@@ -39,10 +40,10 @@ final class ClassInfo implements ClassName
/** @var self|false|null */
private $parent = false;
/** @var HasName[] */
/** @var PropertyMetadata[] */
private $virtualProperties = [];
/** @var HasName[] */
/** @var PropertyMetadata[] */
private $concreteProperties = [];
/** @var self[] */
......@@ -57,11 +58,11 @@ final class ClassInfo implements ClassName
/**
* ClassInfo constructor.
*
* @param ClassName $class
* @param HasName[] $properties
* @param bool $abstract
* @param ClassName $class
* @param PropertyMetadata[] $properties
* @param bool $abstract
*/
public function __construct(ClassName $class, array $properties = [], bool $abstract)
public function __construct(ClassName $class, array $properties = [], bool $abstract = false)
{
$this->class = $class;
$this->abstract = $abstract;
......@@ -99,7 +100,7 @@ final class ClassInfo implements ClassName
/**
* Get properties.
*
* @return HasName[]
* @return PropertyMetadata[]
*/
public function getVirtualProperties(): array
{
......@@ -109,7 +110,7 @@ final class ClassInfo implements ClassName
/**
* Get properties.
*
* @return HasName[]
* @return PropertyMetadata[]
*/
public function getConcreteProperties(): array
{
......
......@@ -62,7 +62,7 @@ abstract class AbstractType implements Type
}
/**
* @return string
* @return mixed
*/
public function jsonSerialize()
{
......
......@@ -167,8 +167,6 @@ class AnonymousObject extends AbstractType
}
/**
* @param bool $multiline
*
* @return array
*/
protected function getMethodDeclarations(): array
......
......@@ -122,24 +122,6 @@ final class Repository extends ClassType
return $this->identifier;
}
/**
* {@inheritdoc}
*/
protected function getMethodDeclarations(): array
{
$parts = $this->getStaticMethodDeclarations();
$parts[] = $this->getConstructor();
$parts[] = $this->getResolveImplementation();
foreach ($this->getOperations() as $operation) {
$parts[] = $operation->getDeclaration() . "\n";
}
return $parts;
}
/**
* {@inheritdoc}
*/
......@@ -195,77 +177,6 @@ CODE
);
}
/**
* @return array
*/
private function getStaticMethodDeclarations(): array
{
if (!$this->iri) {
return [];
}
$parts = [];
// Vérification d'IRI
$parts[] = sprintf(
/* @lang typescript */
<<<'CODE'
/**
* Regexp pour reconnaître une IRI de cette ressource.
*/
public static readonly IRI_PATTERN = /^%s$/ui;
/**
* Vérifie si le paramètre est une IRI valide de ce repository.
*/
public static isIRI(data: string): data is IRI<%s> {
return %s.IRI_PATTERN.test(data);
}
CODE
,
$this->iri->getPattern(),
$this->resourceType->getUsage(),
$this->getName()
);
$idProp = $this->identifier;
$idParam = $this->iri->getIdentifier();
if ($idProp && $idParam) {
$idType = $idProp->getType();
$parts[] = sprintf(
/* @lang typescript */
<<<'CODE'
/**
* Extrait l'identifiant d'une IRI ou vérifie un identifiant.
*/
public static getID(data: %s): %s {
const match = %s.IRI_PATTERN.exec(data);
if (match !== null) {
return %s;
}
if (%s) {
return %s;
}
throw new Error(`Cannot extract %s id from ${data}`);
}
CODE
,
$idParam->getType()->getUsage(),
$idType->getUsage(),
$this->getName(),
$idType->castToStringOrStringArray('match[1]'),
$idType->checkType('data'),
$idType->castToStringOrStringArray('data'),
$this->getResourceName()
);
}
return $parts;
}
/**
* {@inheritdoc}
*/
......
......@@ -42,7 +42,7 @@ class Parameter implements \IteratorAggregate, \JsonSerializable
private $optional = false;
/**
* @var string
* @var string|null
*/
private $default;
......
......@@ -36,7 +36,7 @@ class Reference extends AbstractType implements Deferred
/** @var string */
private $name;
/** @var bool */
/** @var int */
private $state = self::UNRESOLVED;
/**
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment