Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 12 additions & 10 deletions castor.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,35 +11,37 @@
use function Castor\PHPQa\phpstan;
use function Castor\run;

const PHP_CS_FIXER_VERSION = '3.95.1';

#[AsTask('cs:check', namespace: 'qa', description: 'Check for coding standards without fixing them')]
function qa_cs_check()
function qa_cs_check(): void
{
php_cs_fixer(['fix', '--config', __DIR__ . '/.php-cs-fixer.php', '--dry-run', '--diff'], '3.92.3', [
php_cs_fixer(['fix', '--config', __DIR__ . '/.php-cs-fixer.php', '--dry-run', '--diff'], PHP_CS_FIXER_VERSION, [
'kubawerlos/php-cs-fixer-custom-fixers' => '^3.21',
]);
}

#[AsTask('cs:fix', namespace: 'qa', description: 'Fix all coding standards', aliases: ['cs'])]
function qa_cs_fix()
function qa_cs_fix(): void
{
php_cs_fixer(['fix', '--config', __DIR__ . '/.php-cs-fixer.php', '-v'], '3.92.3', [
php_cs_fixer(['fix', '--config', __DIR__ . '/.php-cs-fixer.php', '-v'], PHP_CS_FIXER_VERSION, [
'kubawerlos/php-cs-fixer-custom-fixers' => '^3.21',
]);
}

#[AsTask('phpstan', namespace: 'qa', description: 'Run PHPStan for static analysis', aliases: ['phpstan'])]
function qa_phpstan(bool $generateBaseline = false)
function qa_phpstan(bool $generateBaseline = false): void
{
$params = ['analyse', '--configuration', __DIR__ . '/phpstan.neon', '--memory-limit=-1', '-v'];
if ($generateBaseline) {
$params[] = '--generate-baseline';
}

phpstan($params, '1.12.23');
phpstan($params, '2.1.51');
}

#[AsTask('mapper', namespace: 'debug', description: 'Debug a mapper', aliases: ['debug'])]
function debug_mapper(string $source, string $target, string $load = '')
function debug_mapper(string $source, string $target, string $load = ''): void
{
require_once __DIR__ . '/vendor/autoload.php';

Expand Down Expand Up @@ -79,13 +81,13 @@ function debug_mapper(string $source, string $target, string $load = '')
}

#[AsTask('install', namespace: 'doc', description: 'Install tool for documentation (need poetry)')]
function doc_install()
function doc_install(): void
{
run('poetry install');
}

#[AsTask('server', namespace: 'doc', description: 'Serve documentation')]
function doc_serve()
function doc_serve(): void
{
run('poetry run mkdocs serve -a localhost:8000');
}
Expand Down Expand Up @@ -113,7 +115,7 @@ function build_assets(): void
}

#[AsTask('build-github-pages', namespace: 'doc', description: 'Serve documentation')]
function doc_build_github_pages()
function doc_build_github_pages(): void
{
// clean .build directory
run('rm -rf ./.build', context: context()->withAllowFailure());
Expand Down
55 changes: 46 additions & 9 deletions phpstan.neon
Original file line number Diff line number Diff line change
@@ -1,12 +1,49 @@
parameters:
level: max
paths:
- src/
level: max
paths:
- src/

tmpDir: cache
tmpDir: cache
treatPhpDocTypesAsCertain: false

ignoreErrors:
-
message: "#^Method AutoMapper\\\\ObjectMapper\\\\ObjectMapper\\:\\:map\\(\\) should return T of object but returns object\\|null\\.$#"
count: 1
path: src/ObjectMapper/ObjectMapper.php
ignoreErrors:
-
message: "#^Method AutoMapper\\\\ObjectMapper\\\\ObjectMapper\\:\\:map\\(\\) should return T of object but returns object\\|null\\.$#"
count: 1
path: src/ObjectMapper/ObjectMapper.php

-
message: '#^Parameter \#2 \$array of function implode expects array\<string\>, array given\.$#'
identifier: argument.type
count: 1
path: src/EventListener/MapListener.php

-
message: '#^Binary operation "\." between mixed and string results in an error\.$#'
identifier: binaryOp.invalid
count: 1
path: src/EventListener/MapToContextListener.php

-
message: '#^Parameter \$mapping of class AutoMapper\\Metadata\\Discriminator constructor expects array\<string, class\-string\>, array given\.$#'
identifier: argument.type
count: 2
path: src/EventListener/Symfony/ClassDiscriminatorListener.php

-
message: '#^Call to function function_exists\(\) with callable\-string will always evaluate to true\.$#'
identifier: function.alreadyNarrowedType
count: 1
path: src/Generator/PropertyConditionsGenerator.php

-
message: '#^Method AutoMapper\\Loader\\FileLoader\:\:getRegistry\(\) should return array\<class\-string, string\> but returns array\.$#'
identifier: return.type
count: 1
path: src/Loader/FileLoader.php

-
message: '#^Property AutoMapper\\Loader\\FileLoader\:\:\$registry \(array\<class\-string, string\>\) does not accept mixed\.$#'
identifier: assign.propertyType
count: 1
path: src/Loader/FileLoader.php
24 changes: 12 additions & 12 deletions src/Attribute/MapFrom.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,18 @@
final readonly class MapFrom
{
/**
* @param class-string<object>|'array'|array<class-string<object>|'array'>|null $source The specific source class name or array. If null this attribute will be used for all source classes.
* @param string|null $property The source property name. If null, the target property name will be used.
* @param int|null $maxDepth The maximum depth of the mapping. If null, the default max depth will be used.
* @param string|callable(mixed $value, object|array<string, mixed> $source, array<string, mixed> $context): mixed $transformer A transformer id or a callable that transform the value during mapping
* @param bool|null $ignore If true, the property will be ignored during mapping
* @param string|null $if The condition to map the property, using the expression language
* @param string[]|null $groups The groups to map the property
* @param string|null $dateTimeFormat The date-time format to use when transforming this property
* @param bool|null $extractTypesFromGetter If true, the types will be extracted from the getter method
* @param bool|null $identifier If true, the property will be used as an identifier
* @param Type|string|null $sourcePropertyType Override the source property type, where this property is mapped from
* @param Type|string|null $targetPropertyType Override the target property type, which in this case is the property type where the attribute is defined
* @param class-string<object>|'array'|array<class-string<object>|'array'>|null $source The specific source class name or array. If null this attribute will be used for all source classes.
* @param string|null $property The source property name. If null, the target property name will be used.
* @param int|null $maxDepth The maximum depth of the mapping. If null, the default max depth will be used.
* @param string|callable(mixed $value, object|array<string, mixed> $source, array<string, mixed> $context): mixed|null $transformer A transformer id or a callable that transform the value during mapping
* @param bool|null $ignore If true, the property will be ignored during mapping
* @param string|null $if The condition to map the property, using the expression language
* @param string[]|null $groups The groups to map the property
* @param string|null $dateTimeFormat The date-time format to use when transforming this property
* @param bool|null $extractTypesFromGetter If true, the types will be extracted from the getter method
* @param bool|null $identifier If true, the property will be used as an identifier
* @param Type|string|null $sourcePropertyType Override the source property type, where this property is mapped from
* @param Type|string|null $targetPropertyType Override the target property type, which in this case is the property type where the attribute is defined
*/
public function __construct(
public string|array|null $source = null,
Expand Down
3 changes: 3 additions & 0 deletions src/AttributeReference/ReflectionReference.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ public static function fromMethod(string $className, string $methodName): self
return self::$method[$key];
}

/**
* @param class-string $className
*/
public static function fromProperty(string $className, string $propertyName): self
{
$key = $className . '::$' . $propertyName;
Expand Down
8 changes: 3 additions & 5 deletions src/AutoMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,9 @@ public function getMapper(string $source, string $target): MapperInterface

public function map(array|object $source, string|array|object $target, array $context = []): array|object|null
{
$sourceType = $targetType = null;

if (\is_object($source)) {
/** @var class-string<object> $sourceType */
$sourceType = $source::class;
} elseif (\is_array($source)) {
} else {
$sourceType = 'array';
}

Expand All @@ -102,7 +99,7 @@ public function map(array|object $source, string|array|object $target, array $co
$targetType = 'array';
$context[MapperContext::TARGET_TO_POPULATE] = $target;
$context[MapperContext::DEEP_TARGET_TO_POPULATE] ??= true;
} elseif (\is_string($target)) {
} else {
$targetType = $target;
}

Expand All @@ -116,6 +113,7 @@ public function map(array|object $source, string|array|object $target, array $co
public function mapCollection(iterable $collection, string $target, array $context = []): array
{
$output = [];
/** @var string|int $k */
foreach ($collection as $k => $item) {
if (\is_array($item) && 'array' === $target) {
throw new InvalidMappingException('Cannot map this value, both source and target are array.');
Expand Down
2 changes: 1 addition & 1 deletion src/EventListener/MapListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ protected function getTransformerFromMapAttribute(string $class, MapTo|MapFrom $
$transformer = new PropertyTransformer($transformerCallable);
} elseif (!\is_object($transformerCallable) && \is_callable($transformerCallable, false, $callableName)) {
$transformer = new CallableTransformer($callableName);
} elseif (\is_object($transformerCallable) && \is_callable($transformerCallable)) {
} elseif (\is_callable($transformerCallable)) {
$transformer = new ReferenceTransformer($reference);
} elseif (\is_string($transformerCallable) && method_exists($class, $transformerCallable)) {
$reflMethod = new \ReflectionMethod($class, $transformerCallable);
Expand Down
2 changes: 1 addition & 1 deletion src/EventListener/MapperListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ private function getMapperAttribute(GenerateMapperEvent $event, bool $allowParen
}

// sort by priority
usort($mappers, fn (array $a, array $b) => $a[0]->priority <=> $b[0]->priority);
usort($mappers, static fn (array $a, array $b) => $a[0]->priority <=> $b[0]->priority);

return $mappers[0];
}
Expand Down
2 changes: 1 addition & 1 deletion src/Extractor/AddRemoveWriteMutator.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public function getExpression(Expr $output, Expr $value, bool $byRef = false): E
]);
}

public function getRemoveExpression(Expr $object, Expr $value): ?Expr
public function getRemoveExpression(Expr $object, Expr $value): Expr
{
return new Expr\MethodCall($object, $this->removeMethodName, [
new Arg($value),
Expand Down
2 changes: 1 addition & 1 deletion src/Extractor/ArrayReadAccessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public function getExpression(Expr $input, bool $target = false): Expr
return new Expr\ArrayDimFetch($input, new Scalar\String_($this->property));
}

public function getIsDefinedExpression(Expr\Variable $input, bool $nullable = false, bool $target = false): ?Expr
public function getIsDefinedExpression(Expr\Variable $input, bool $nullable = false, bool $target = false): Expr
{
if ($this->isArrayAccess) {
return new Expr\MethodCall($input, 'offsetExists', [new Arg(new Scalar\String_($this->property))]);
Expand Down
2 changes: 1 addition & 1 deletion src/Extractor/FromSourceMappingExtractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ private function transformSourceType(string $target, ?Type $type = null): ?Type
}

// Transform datetime to string
if ($type instanceof Type\ObjectType && $type->getClassName() !== null && (\DateTimeInterface::class === $type->getClassName() || is_subclass_of($type->getClassName(), \DateTimeInterface::class))) {
if ($type instanceof Type\ObjectType && (\DateTimeInterface::class === $type->getClassName() || is_subclass_of($type->getClassName(), \DateTimeInterface::class))) {
return Type::string();
}

Expand Down
2 changes: 1 addition & 1 deletion src/Extractor/FromTargetMappingExtractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ private function transformTargetType(string $source, ?Type $type = null): ?Type
}

// Transform datetime to string
if ($type instanceof Type\ObjectType && $type->getClassName() !== null && (\DateTimeInterface::class === $type->getClassName() || is_subclass_of($type->getClassName(), \DateTimeInterface::class))) {
if ($type instanceof Type\ObjectType && (\DateTimeInterface::class === $type->getClassName() || is_subclass_of($type->getClassName(), \DateTimeInterface::class))) {
return Type::string();
}

Expand Down
2 changes: 1 addition & 1 deletion src/Extractor/MappingExtractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public function __construct(
}

/**
* @return list<string>
* @return array<string>
*/
public function getProperties(string $class, bool $withConstructorParameters = false): iterable
{
Expand Down
2 changes: 1 addition & 1 deletion src/Extractor/MethodReadAccessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
* @param array<string, string> $context
*/
public function __construct(
public string $property,
public ?string $property,
public string $method,
public string $sourceClass,
public bool $private = false,
Expand Down
2 changes: 1 addition & 1 deletion src/Extractor/PropertyReadAccessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public function getExpression(Expr $input, bool $target = false): Expr
return new Expr\PropertyFetch($input, $this->property);
}

public function getIsDefinedExpression(Expr\Variable $input, bool $nullable = false, bool $target = false): ?Expr
public function getIsDefinedExpression(Expr\Variable $input, bool $nullable = false, bool $target = false): Expr
{
if ($this->private) {
/*
Expand Down
8 changes: 4 additions & 4 deletions src/GeneratedMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,19 +58,19 @@ public function getTargetHash(mixed $value): string
/** @var array<string, callable(): mixed> */
protected array $extractCallbacks = [];

/** @var array<string, callable(): bool>) */
/** @var array<string, callable(): bool> */
protected array $extractIsNullCallbacks = [];

/** @var array<string, callable(): bool>) */
/** @var array<string, callable(): bool> */
protected array $extractIsUndefinedCallbacks = [];

/** @var array<string, callable(): mixed> */
protected array $extractTargetCallbacks = [];

/** @var array<string, callable(): bool>) */
/** @var array<string, (callable(): bool)> */
protected array $extractTargetIsNullCallbacks = [];

/** @var array<string, callable(): bool>) */
/** @var array<string, (callable(): bool)> */
protected array $extractTargetIsUndefinedCallbacks = [];

/** @var Target|\ReflectionClass<object> */
Expand Down
10 changes: 5 additions & 5 deletions src/Generator/CreateTargetStatementsGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public function __construct(
* }
* ```
*
* @return list<Stmt>
* @return Stmt[]
*/
public function generate(GeneratorMetadata $metadata, VariableRegistry $variableRegistry, bool $callDoConstruct): array
{
Expand Down Expand Up @@ -218,7 +218,7 @@ private function targetAsStdClass(GeneratorMetadata $metadata): ?Stmt
}

/**
* @return list<Stmt>
* @return Stmt[]
*/
public function getConstructStatements(GeneratorMetadata $metadata): array
{
Expand Down Expand Up @@ -290,7 +290,7 @@ public function getConstructStatements(GeneratorMetadata $metadata): array
* }
* ```
*
* @return list<Stmt>|null
* @return Stmt[]|null
*/
private function constructorArgument(Expr\ArrayDimFetch $assignVar, GeneratorMetadata $metadata, PropertyMetadata $propertyMetadata, \ReflectionParameter $parameter): ?array
{
Expand All @@ -299,7 +299,7 @@ private function constructorArgument(Expr\ArrayDimFetch $assignVar, GeneratorMet
$conditionDefined = $propertyMetadata->source->accessor?->getIsDefinedExpression($variableRegistry->getSourceInput(), $parameter->allowsNull());

if (null === $fieldValueExpr) {
if (!($propertyMetadata->transformer instanceof AllowNullValueTransformerInterface)) {
if (!$propertyMetadata->transformer instanceof AllowNullValueTransformerInterface) {
return null;
}

Expand Down Expand Up @@ -393,7 +393,7 @@ private function constructorArgument(Expr\ArrayDimFetch $assignVar, GeneratorMet
* }
* ```
*
* @return list<Stmt>
* @return Stmt[]
*/
private function constructorArgumentWithoutSource(Expr\ArrayDimFetch $assignVar, GeneratorMetadata $metadata, \ReflectionParameter $constructorParameter): array
{
Expand Down
2 changes: 1 addition & 1 deletion src/Generator/IdentifierHashGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
final readonly class IdentifierHashGenerator
{
/**
* @return list<Stmt>
* @return Stmt[]
*/
private function getStatements(GeneratorMetadata $metadata, bool $fromSource): array
{
Expand Down
2 changes: 1 addition & 1 deletion src/Generator/InjectMapperMethodStatementsGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public function __construct()
}

/**
* @return list<Stmt>
* @return Stmt[]
*/
public function getStatements(Expr\Variable $automapperRegistryVariable, GeneratorMetadata $metadata): array
{
Expand Down
Loading
Loading