8000 [Finder] Handle filtering of recursive iterators and use it to skip l… · symfony/symfony@84b2512 · GitHub
[go: up one dir, main page]

Skip to content

Commit 84b2512

Browse files
[Finder] Handle filtering of recursive iterators and use it to skip looping over excluded directories
1 parent 7d343e6 commit 84b2512

File tree

7 files changed

+47
-24
lines changed

7 files changed

+47
-24
lines changed

src/Symfony/Component/Finder/Adapter/PhpAdapter.php

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,13 @@ public function searchInDirectory($dir)
3131
$flags |= \RecursiveDirectoryIterator::FOLLOW_SYMLINKS;
3232
}
3333

34-
$iterator = new \RecursiveIteratorIterator(
35-
new Iterator\RecursiveDirectoryIterator($dir, $flags, $this->ignoreUnreadableDirs),
36-
\RecursiveIteratorIterator::SELF_FIRST
37-
);
34+
$iterator = new Iterator\RecursiveDirectoryIterator($dir, $flags, $this->ignoreUnreadableDirs);
35+
36+
if ($this->exclude) {
37+
$iterator = new Iterator\ExcludeDirectoryFilterIterator($iterator, $this->exclude);
38+
}
39+
40+
$iterator = new \RecursiveIteratorIterator($iterator, \RecursiveIteratorIterator::SELF_FIRST);
3841

3942
if ($this->minDepth > 0 || $this->maxDepth < PHP_INT_MAX) {
4043
$iterator = new Iterator\DepthRangeFilterIterator($iterator, $this->minDepth, $this->maxDepth);
@@ -44,10 +47,6 @@ public function searchInDirectory($dir)
4447
$iterator = new Iterator\FileTypeFilterIterator($iterator, $this->mode);
4548
}
4649

47-
if ($this->exclude) {
48-
$iterator = new Iterator\ExcludeDirectoryFilterIterator($iterator, $this->exclude);
49-
}
50-
5150
if ($this->names || $this->notNames) {
5251
$iterator = new Iterator\FilenameFilterIterator($iterator, $this->names, $this->notNames);
5352
}

src/Symfony/Component/Finder/Iterator/CustomFilterIterator.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,10 @@ public function accept()
5454

5555
foreach ($this->filters as $filter) {
5656
if (false === call_user_func($filter, $fileinfo)) {
57-
return false;
57+
return $this->acceptChildren = false;
5858
}
5959
}
6060

61-
return true;
61+
return $this->acceptChildren = true;
6262
}
6363
}

src/Symfony/Component/Finder/Iterator/DateRangeFilterIterator.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,16 +45,16 @@ public function accept()
4545
$fileinfo = $this->current();
4646

4747
if (!file_exists($fileinfo->getRealPath())) {
48-
return false;
48+
return $this->acceptChildren = false;
4949
}
5050

5151
$filedate = $fileinfo->getMTime();
5252
foreach ($this->comparators as $compare) {
5353
if (!$compare->test($filedate)) {
54-
return false;
54+
return $this->acceptChildren = false;
5555
}
5656
}
5757

58-
return true;
58+
return $this->acceptChildren = true;
5959
}
6060
}

src/Symfony/Component/Finder/Iterator/ExcludeDirectoryFilterIterator.php

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class ExcludeDirectoryFilterIterator extends FilterIterator
2929
public function __construct(\Iterator $iterator, array $directories)
3030
{
3131
foreach ($directories as $directory) {
32-
$this->patterns[] = '#(^|/)'.preg_quote($directory, '#').'(/|$)#';
32+
$this->patterns[$directory] = '#(^|/)'.preg_quote($directory, '#').'(/|$)#';
33 57AE 33
}
3434

3535
parent::__construct($iterator);
@@ -42,14 +42,23 @@ public function __construct(\Iterator $iterator, array $directories)
4242
*/
4343
public function accept()
4444
{
45-
$path = $this->isDir() ? $this->current()->getRelativePathname() : $this->current()->getRelativePath();
45+
$path = $this->current();
46+
47+
if (isset($this->patterns[$path->getFilename()])) {
48+
return $this->acceptChildren = false;
49+
}
50+
if ($this->getInnerIterator() instanceof \RecursiveIterator) {
51+
return $this->acceptChildren = true;
52< B41A /code>+
}
53+
54+
$path = $this->isDir() ? $path->getRelativePathname() : $path->getRelativePath();
4655
$path = str_replace('\\', '/', $path);
4756
foreach ($this->patterns as $pattern) {
4857
if (preg_match($pattern, $path)) {
49-
return false;
58+
return $this->acceptChildren = false;
5059
}
5160
}
5261

53-
return true;
62+
return $this->acceptChildren = true;
5463
}
5564
}

src/Symfony/Component/Finder/Iterator/FilenameFilterIterator.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public function accept()
3232
// should at least not match one rule to exclude
3333
foreach ($this->noMatchRegexps as $regex) {
3434
if (preg_match($regex, $filename)) {
35-
return false;
35+
return $this->acceptChildren = false;
3636
}
3737
}
3838

@@ -42,12 +42,12 @@ public function accept()
4242
$match = false;
4343
foreach ($this->matchRegexps as $regex) {
4444
if (preg_match($regex, $filename)) {
45-
return true;
45+
return $this->acceptChildren = true;
4646
}
4747
}
4848
}
4949

50-
return $match;
50+
return $this->acceptChildren = $match;
5151
}
5252

5353
/**

src/Symfony/Component/Finder/Iterator/FilterIterator.php

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,23 @@
1818
*
1919
* @author Alex Bogomazov
2020
*/
21-
abstract class FilterIterator extends \FilterIterator
21+
abstract class FilterIterator extends \FilterIterator implements \RecursiveIterator
2222
{
23+
/**
24+
* @var bool The memoized return value of $this->accept() when having a recursive inner iterator makes sense.
25+
*/
26+
protected $acceptChildren = true;
27+
28+
public function hasChildren()
29+
{
30+
return $this->acceptChildren && $this->getInnerIterator() instanceof \RecursiveIterator && $this->getInnerIterator()->hasChildren();
31+
}
32+
33+
public function getChildren()
34+
{
35+
return $this->getInnerIterator()->getChildren();
36+
}
37+
2338
/**
2439
* This is a workaround for the problem with \FilterIterator leaving inner \FilesystemIterator in wrong state after
2540
* rewind in some cases.

src/Symfony/Component/Finder/Iterator/PathFilterIterator.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public function accept()
3535
// should at least not match one rule to exclude
3636
foreach ($this->noMatchRegexps as $regex) {
3737
if (preg_match($regex, $filename)) {
38-
return false;
38+
return $this->acceptChildren = false;
3939
}
4040
}
4141

@@ -45,12 +45,12 @@ public function accept()
4545
$match = false;
4646
foreach ($this->matchRegexps as $regex) {
4747
if (preg_match($regex, $filename)) {
48-
return true;
48+
return $this->acceptChildren = true;
4949
}
5050
}
5151
}
5252

53-
return $match;
53+
return $this->acceptChildren = $match;
5454
}
5555

5656
/**

0 commit comments

Comments
 (0)
0