Skip to content
Closed
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
28 changes: 17 additions & 11 deletions src/Persistence/Mapping/Driver/ColocatedMappingDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
use function array_unique;
use function assert;
use function get_declared_classes;
use function in_array;
use function is_dir;
use function preg_match;
use function preg_quote;
Expand Down Expand Up @@ -161,8 +160,12 @@ public function getAllClassNames(): array
}

/** @var iterable<string> $sourceFilePathNames */
$sourceFilePathNames = $this->sourceFilePathNames ?? $this->pathNameIterator($filesIterator);
$includedFiles = [];
$sourceFilePathNames = $this->mergeIterables(
$this->sourceFilePathNames ?? [],
new PathNameIterator($filesIterator),
);
/** @var array<string,true> $includedFiles */
$includedFiles = [];

foreach ($sourceFilePathNames as $sourceFile) {
if (preg_match('(^phar:)i', $sourceFile) === 0) {
Expand All @@ -183,7 +186,7 @@ public function getAllClassNames(): array

require_once $sourceFile;

$includedFiles[] = $sourceFile;
$includedFiles[$sourceFile] = true;
}

$classes = [];
Expand All @@ -194,7 +197,7 @@ public function getAllClassNames(): array

$sourceFile = $rc->getFileName();

if (! in_array($sourceFile, $includedFiles, true) || $this->isTransient($className)) {
if (! isset($includedFiles[$sourceFile]) || $this->isTransient($className)) {
continue;
}

Expand All @@ -207,14 +210,17 @@ public function getAllClassNames(): array
}

/**
* @param iterable<SplFileInfo> $filesIterator
* @param iterable<TKey, T> $iterable1
* @param iterable<TKey, T> $iterable2
*
* @return Generator<int,string>
* @return Generator<TKey, T>
*
* @template TKey
* @template T
*/
private function pathNameIterator(iterable $filesIterator): Generator
private function mergeIterables(iterable $iterable1, iterable $iterable2): Generator
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is rather appending $iterable2 to $iterable1 than merging.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you propose naming it as concatIterables()?

"Appending" sounds with the tone of modifying the iterable, while it's actually combining them into a single iterable, doing no modification to the original.

Dictionary-wise, "merge" looks good as it means "combine or cause to combine to form a single entity."

{
foreach ($filesIterator as $file) {
yield $file->getPathname();
}
yield from $iterable1;
yield from $iterable2;
}
}
27 changes: 27 additions & 0 deletions src/Persistence/Mapping/Driver/PathNameIterator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

namespace Doctrine\Persistence\Mapping\Driver;

use Generator;
use IteratorAggregate;
use SplFileInfo;

/** @implements IteratorAggregate<int,string> */
final class PathNameIterator implements IteratorAggregate
{
public function __construct(
/** @var iterable<SplFileInfo> */
private readonly iterable $filesIterator,
) {
}

/** @return Generator<int,string> */
public function getIterator(): Generator
{
foreach ($this->filesIterator as $file) {
yield $file->getPathname();
}
}
}
16 changes: 16 additions & 0 deletions tests/Persistence/Mapping/ColocatedMappingDriverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,22 @@ public function testGetAllClassNamesForIterableFilePathNames(): void
self::assertSame([Entity::class], $classes, 'The driver should only return the class names from the provided file path names, excluding transient class names.');
}

public function testGetAllClassNamesWorksForBothIterableFilePathNamesAndRetroactivelyAddedDirectoryPaths(): void
{
$driver = $this->createFilePathNamesDriver([__DIR__ . '/_files/colocated/Entity.php']);

$driver->addPaths([__DIR__ . '/_files/colocated/']);

$classes = $driver->getAllClassNames();
sort($classes);

self::assertSame(
[Entity::class, EntityFixture::class],
$classes,
'The driver should return class names from both the provided file path names and the retroactively added directory paths (these should not be ignored).',
);
}

/** @return Generator<string, array{string}> */
public static function pathProvider(): Generator
{
Expand Down