Skip to content

Commit

Permalink
refactor: split Generator class in several classes (#35)
Browse files Browse the repository at this point in the history
  • Loading branch information
nikophil authored Jan 15, 2024
1 parent b6a407d commit 1486a85
Show file tree
Hide file tree
Showing 31 changed files with 1,816 additions and 875 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed
- [GH#27](https://github.com/jolicode/automapper/pull/27) Use PhpStanExtractor instead of PhpDocExtractor
- [GH#35](https://github.com/jolicode/automapper/pull/35) Refactoring Mapper Generator

## [8.1.0] - 2023-12-14
### Added
Expand Down
12 changes: 5 additions & 7 deletions src/AutoMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
use AutoMapper\Extractor\FromTargetMappingExtractor;
use AutoMapper\Extractor\MapToContextPropertyInfoExtractorDecorator;
use AutoMapper\Extractor\SourceTargetMappingExtractor;
use AutoMapper\Generator\Generator;
use AutoMapper\Generator\MapperGenerator;
use AutoMapper\Generator\Shared\ClassDiscriminatorResolver;
use AutoMapper\Loader\ClassLoaderInterface;
use AutoMapper\Loader\EvalLoader;
use AutoMapper\Transformer\ArrayTransformerFactory;
Expand All @@ -28,7 +29,6 @@
use AutoMapper\Transformer\TransformerFactoryInterface;
use AutoMapper\Transformer\UniqueTypeTransformerFactory;
use Doctrine\Common\Annotations\AnnotationReader;
use PhpParser\ParserFactory;
use Symfony\Component\PropertyInfo\Extractor\PhpStanExtractor;
use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor;
use Symfony\Component\PropertyInfo\PropertyInfoExtractor;
Expand Down Expand Up @@ -178,13 +178,11 @@ public static function create(

if (null === $loader) {
$loader = new EvalLoader(
new Generator(
new MapperGenerator(
new CustomTransformerExtractor(new ClassMethodToCallbackExtractor()),
(new ParserFactory())->create(ParserFactory::PREFER_PHP7),
new ClassDiscriminatorFromClassMetadata($classMetadataFactory),
new ClassDiscriminatorResolver(new ClassDiscriminatorFromClassMetadata($classMetadataFactory)),
$allowReadOnlyTargetToPopulate
)
);
));
}

$flags = ReflectionExtractor::ALLOW_PUBLIC | ReflectionExtractor::ALLOW_PROTECTED | ReflectionExtractor::ALLOW_PRIVATE;
Expand Down
3 changes: 3 additions & 0 deletions src/Extractor/CustomTransformerExtractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
use PhpParser\Node\Arg;
use PhpParser\Node\Expr;

/**
* @internal
*/
final readonly class CustomTransformerExtractor
{
public function __construct(
Expand Down
7 changes: 5 additions & 2 deletions src/Extractor/FromSourceMappingExtractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace AutoMapper\Extractor;

use AutoMapper\Exception\InvalidMappingException;
use AutoMapper\MapperMetadataInterface;
use AutoMapper\MapperGeneratorMetadataInterface;
use AutoMapper\Transformer\CustomTransformer\CustomTransformersRegistry;
use AutoMapper\Transformer\TransformerFactoryInterface;
use Symfony\Component\PropertyInfo\PropertyInfoExtractorInterface;
Expand All @@ -22,6 +22,8 @@
* Can use a NameConverter to use specific properties name in the target
*
* @author Joel Wurtz <[email protected]>
*
* @internal
*/
final class FromSourceMappingExtractor extends MappingExtractor
{
Expand All @@ -39,7 +41,7 @@ public function __construct(
parent::__construct($propertyInfoExtractor, $readInfoExtractor, $writeInfoExtractor, $transformerFactory, $customTransformerRegistry, $classMetadataFactory);
}

public function getPropertiesMapping(MapperMetadataInterface $mapperMetadata): array
public function getPropertiesMapping(MapperGeneratorMetadataInterface $mapperMetadata): array
{
$sourceProperties = $this->propertyInfoExtractor->getProperties($mapperMetadata->getSource());

Expand Down Expand Up @@ -83,6 +85,7 @@ public function getPropertiesMapping(MapperMetadataInterface $mapperMetadata): a
}

$mapping[] = new PropertyMapping(
$mapperMetadata,
$this->getReadAccessor($mapperMetadata->getSource(), $mapperMetadata->getTarget(), $property),
$this->getWriteMutator($mapperMetadata->getSource(), $mapperMetadata->getTarget(), $property),
null,
Expand Down
7 changes: 5 additions & 2 deletions src/Extractor/FromTargetMappingExtractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace AutoMapper\Extractor;

use AutoMapper\Exception\InvalidMappingException;
use AutoMapper\MapperMetadataInterface;
use AutoMapper\MapperGeneratorMetadataInterface;
use AutoMapper\Transformer\CustomTransformer\CustomTransformersRegistry;
use AutoMapper\Transformer\TransformerFactoryInterface;
use Symfony\Component\PropertyInfo\PropertyInfoExtractorInterface;
Expand All @@ -23,6 +23,8 @@
* Can use a NameConverter to use specific properties name in the source
*
* @author Joel Wurtz <[email protected]>
*
* @internal
*/
final class FromTargetMappingExtractor extends MappingExtractor
{
Expand All @@ -40,7 +42,7 @@ public function __construct(
parent::__construct($propertyInfoExtractor, $readInfoExtractor, $writeInfoExtractor, $transformerFactory, $customTransformerRegistry, $classMetadataFactory);
}

public function getPropertiesMapping(MapperMetadataInterface $mapperMetadata): array
public function getPropertiesMapping(MapperGeneratorMetadataInterface $mapperMetadata): array
{
$targetProperties = array_unique($this->propertyInfoExtractor->getProperties($mapperMetadata->getTarget()) ?? []);

Expand Down Expand Up @@ -78,6 +80,7 @@ public function getPropertiesMapping(MapperMetadataInterface $mapperMetadata): a
}

$mapping[] = new PropertyMapping(
$mapperMetadata,
$this->getReadAccessor($mapperMetadata->getSource(), $mapperMetadata->getTarget(), $property),
$this->getWriteMutator($mapperMetadata->getSource(), $mapperMetadata->getTarget(), $property, [
'enable_constructor_extraction' => false,
Expand Down
3 changes: 3 additions & 0 deletions src/Extractor/MapToContextPropertyInfoExtractorDecorator.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
use Symfony\Component\PropertyInfo\PropertyWriteInfo;
use Symfony\Component\PropertyInfo\PropertyWriteInfoExtractorInterface;

/**
* @internal
*/
final readonly class MapToContextPropertyInfoExtractorDecorator implements PropertyListExtractorInterface, PropertyTypeExtractorInterface, PropertyAccessExtractorInterface, PropertyInitializableExtractorInterface, PropertyReadInfoExtractorInterface, PropertyWriteInfoExtractorInterface, ConstructorArgumentTypeExtractorInterface
{
public function __construct(
Expand Down
4 changes: 2 additions & 2 deletions src/Extractor/MappingExtractorInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace AutoMapper\Extractor;

use AutoMapper\MapperMetadataInterface;
use AutoMapper\MapperGeneratorMetadataInterface;

/**
* Extracts mapping.
Expand All @@ -20,7 +20,7 @@ interface MappingExtractorInterface
*
* @return PropertyMapping[]
*/
public function getPropertiesMapping(MapperMetadataInterface $mapperMetadata): array;
public function getPropertiesMapping(MapperGeneratorMetadataInterface $mapperMetadata): array;

/**
* Extracts read accessor for a given source, target and property.
Expand Down
34 changes: 19 additions & 15 deletions src/Extractor/PropertyMapping.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,43 +4,47 @@

namespace AutoMapper\Extractor;

use AutoMapper\MapperGeneratorMetadataInterface;
use AutoMapper\Transformer\CustomTransformer\CustomTransformerInterface;
use AutoMapper\Transformer\TransformerInterface;

/**
* Property mapping.
*
* @author Joel Wurtz <[email protected]>
*
* @internal
*/
final class PropertyMapping
final readonly class PropertyMapping
{
public function __construct(
public readonly ?ReadAccessor $readAccessor,
public readonly ?WriteMutator $writeMutator,
public readonly ?WriteMutator $writeMutatorConstructor,
public MapperGeneratorMetadataInterface $mapperMetadata,
public ?ReadAccessor $readAccessor,
public ?WriteMutator $writeMutator,
public ?WriteMutator $writeMutatorConstructor,
/** @var TransformerInterface|class-string<CustomTransformerInterface> */
public readonly TransformerInterface|string $transformer,
public readonly string $property,
public readonly bool $checkExists = false,
public readonly ?array $sourceGroups = null,
public readonly ?array $targetGroups = null,
public readonly ?int $maxDepth = null,
public readonly bool $sourceIgnored = false,
public readonly bool $targetIgnored = false,
public readonly bool $isPublic = false,
public TransformerInterface|string $transformer,
public string $property,
public bool $checkExists = false,
public ?array $sourceGroups = null,
public ?array $targetGroups = null,
public ?int $maxDepth = null,
public bool $sourceIgnored = false,
public bool $targetIgnored = false,
public bool $isPublic = false,
) {
}

public function shouldIgnoreProperty(bool $shouldMapPrivateProperties = true): bool
{
return $this->sourceIgnored
return !$this->writeMutator
|| $this->sourceIgnored
|| $this->targetIgnored
|| !($shouldMapPrivateProperties || $this->isPublic);
}

/**
* @phpstan-assert-if-false TransformerInterface $this->transformer
* @phpstan-assert-if-false !null $this->readAccessor
*
* @phpstan-assert-if-true string $this->transformer
*/
Expand Down
2 changes: 2 additions & 0 deletions src/Extractor/ReadAccessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
* Read accessor tell how to read from a property.
*
* @author Joel Wurtz <[email protected]>
*
* @internal
*/
final class ReadAccessor
{
Expand Down
8 changes: 6 additions & 2 deletions src/Extractor/SourceTargetMappingExtractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,20 @@

namespace AutoMapper\Extractor;

use AutoMapper\MapperGeneratorMetadataInterface;
use AutoMapper\MapperMetadataInterface;
use Symfony\Component\PropertyInfo\PropertyReadInfo;

/**
* Extracts mapping between two objects, only gives properties that have the same name.
*
* @author Joel Wurtz <[email protected]>
*
* @internal
*/
class SourceTargetMappingExtractor extends MappingExtractor
{
public function getPropertiesMapping(MapperMetadataInterface $mapperMetadata): array
public function getPropertiesMapping(MapperGeneratorMetadataInterface $mapperMetadata): array
{
$sourceProperties = $this->propertyInfoExtractor->getProperties($mapperMetadata->getSource());
$targetProperties = $this->propertyInfoExtractor->getProperties($mapperMetadata->getTarget());
Expand Down Expand Up @@ -61,7 +64,7 @@ public function getPropertiesMapping(MapperMetadataInterface $mapperMetadata): a
return $mapping;
}

private function toPropertyMapping(MapperMetadataInterface $mapperMetadata, string $property, bool $onlyCustomTransformer = false): PropertyMapping|null
private function toPropertyMapping(MapperGeneratorMetadataInterface $mapperMetadata, string $property, bool $onlyCustomTransformer = false): PropertyMapping|null
{
$targetMutatorConstruct = $this->getWriteMutator($mapperMetadata->getSource(), $mapperMetadata->getTarget(), $property, [
'enable_constructor_extraction' => true,
Expand All @@ -85,6 +88,7 @@ private function toPropertyMapping(MapperMetadataInterface $mapperMetadata, stri
}

return new PropertyMapping(
$mapperMetadata,
readAccessor: $this->getReadAccessor($mapperMetadata->getSource(), $mapperMetadata->getTarget(), $property),
writeMutator: $this->getWriteMutator($mapperMetadata->getSource(), $mapperMetadata->getTarget(), $property, [
'enable_constructor_extraction' => false,
Expand Down
2 changes: 2 additions & 0 deletions src/Extractor/WriteMutator.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
* Writes mutator tell how to write to a property.
*
* @author Joel Wurtz <[email protected]>
*
* @internal
*/
final class WriteMutator
{
Expand Down
Loading

0 comments on commit 1486a85

Please sign in to comment.