ClassIterator::not()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
/**
3
 * This program is free software. It comes without any warranty, to
4
 * the extent permitted by applicable law. You can redistribute it
5
 * and/or modify it under the terms of the Do What The Fuck You Want
6
 * To Public License, Version 2, as published by Sam Hocevar. See
7
 * http://www.wtfpl.net/ for more details.
8
 */
9
10
declare(strict_types = 1);
11
12
namespace hanneskod\classtools\Iterator;
13
14
use Symfony\Component\Finder\Finder;
15
use hanneskod\classtools\Transformer\Writer;
16
use hanneskod\classtools\Transformer\MinimizingWriter;
17
use hanneskod\classtools\Iterator\Filter\CacheFilter;
18
use hanneskod\classtools\Iterator\Filter\NameFilter;
19
use hanneskod\classtools\Iterator\Filter\NamespaceFilter;
20
use hanneskod\classtools\Iterator\Filter\NotFilter;
21
use hanneskod\classtools\Iterator\Filter\TypeFilter;
22
use hanneskod\classtools\Iterator\Filter\WhereFilter;
23
use hanneskod\classtools\Exception\LogicException;
24
use hanneskod\classtools\Loader\ClassLoader;
25
use hanneskod\classtools\Exception\ReaderException;
26
27
/**
28
 * Iterate over classes found in filesystem
29
 *
30
 * @author Hannes Forsgård <[email protected]>
31
 */
32
class ClassIterator implements ClassIteratorInterface
33
{
34
    /**
35
     * @var SplFileInfo[] Maps names to SplFileInfo objects
36
     */
37
    private $classMap = [];
38
39
    /**
40
     * @var string[]
41
     */
42
    private $errors = [];
43
44
    /**
45
     * @var ClassLoader
46
     */
47
    private $loader;
48
49
    /**
50
     * Scan filesystem for classes, interfaces and traits
51
     */
52
    public function __construct(Finder $finder = null)
53
    {
54
        /** @var \Symfony\Component\Finder\SplFileInfo $fileInfo */
55
        foreach (($finder ?: []) as $fileInfo) {
56
            $fileInfo = new SplFileInfo($fileInfo);
57
            try {
58
                foreach ($fileInfo->getReader()->getDefinitionNames() as $name) {
59
                    $this->classMap[$name] = $fileInfo;
60
                }
61
            } catch (ReaderException $exception) {
62
                $this->errors[] = $exception->getMessage();
63
            }
64
        }
65
    }
66
67
    /**
68
     * Enable garbage collection of the autoloader at destruct
69
     */
70
    public function __destruct()
71
    {
72
        $this->disableAutoloading();
73
    }
74
75
    public function getErrors(): array
76
    {
77
        return $this->errors;
78
    }
79
80
    public function getClassMap(): array
81
    {
82
        return $this->classMap;
83
    }
84
85
    public function enableAutoloading(): void
86
    {
87
        $this->loader = new ClassLoader($this, true);
88
    }
89
90
    public function disableAutoloading(): void
91
    {
92
        if (isset($this->loader)) {
93
            $this->loader->unregister();
94
            unset($this->loader);
95
        }
96
    }
97
98
    public function getIterator(): iterable
99
    {
100
        /** @var SplFileInfo $fileInfo */
101
        foreach ($this->getClassMap() as $name => $fileInfo) {
102
            try {
103
                yield $name => new \ReflectionClass($name);
104
            } catch (\ReflectionException $e) {
105
                $msg = "Unable to iterate, {$e->getMessage()}, is autoloading enabled?";
106
                throw new LogicException($msg, 0, $e);
107
            }
108
        }
109
    }
110
111
    public function filter(Filter $filter): Filter
112
    {
113
        $filter->bindTo($this);
114
        return $filter;
115
    }
116
117
    public function type(string $typename): Filter
118
    {
119
        return $this->filter(new TypeFilter($typename));
120
    }
121
122
    public function name(string $pattern): Filter
123
    {
124
        return $this->filter(new NameFilter($pattern));
125
    }
126
127
    public function inNamespace(string $namespace): Filter
128
    {
129
        return $this->filter(new NamespaceFilter($namespace));
130
    }
131
132
    public function where(string $methodName, $expectedReturn = true): Filter
133
    {
134
        return $this->filter(new WhereFilter($methodName, $expectedReturn));
135
    }
136
137
    public function not(Filter $filter): Filter
138
    {
139
        return $this->filter(new NotFilter($filter));
140
    }
141
142
    public function cache(): Filter
143
    {
144
        return $this->filter(new CacheFilter);
145
    }
146
147
    public function transform(Writer $writer): string
148
    {
149
        $code = '';
150
151
        /** @var SplFileInfo $fileInfo */
152
        foreach ($this->getClassMap() as $name => $fileInfo) {
153
            $code .= $writer->write($fileInfo->getReader()->read($name)) . "\n";
154
        }
155
156
        return "<?php $code";
157
    }
158
159
    public function minimize(): string
160
    {
161
        return $this->transform(new MinimizingWriter);
162
    }
163
}
164