Completed
Push — develop ( 141adb...8f70d4 )
by Jaap
05:39
created

Parser::forceRebuildIfSettingsHaveModified()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 1
dl 0
loc 10
ccs 0
cts 7
cp 0
crap 6
rs 9.9332
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
/**
5
 * This file is part of phpDocumentor.
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 *
10
 * @author    Mike van Riel <[email protected]>
11
 * @copyright 2010-2018 Mike van Riel / Naenius (http://www.naenius.com)
12
 * @license   http://www.opensource.org/licenses/mit-license.php MIT
13
 * @link      http://phpdoc.org
14
 */
15
16
namespace phpDocumentor\Parser;
17
18
use phpDocumentor\Descriptor\ProjectDescriptorBuilder;
19
use phpDocumentor\Event\Dispatcher;
20
use phpDocumentor\Parser\Event\PreParsingEvent;
21
use phpDocumentor\Parser\Exception\FilesNotFoundException;
22
use phpDocumentor\Reflection\ProjectFactory;
23
use Psr\Log\LoggerInterface;
24
use Psr\Log\LogLevel;
25
use Symfony\Component\Stopwatch\Stopwatch;
26
27
/**
28
 * Class responsible for parsing the given file or files to the intermediate
29
 * structure file.
30
 *
31
 * This class can be used to parse one or more files to the intermediate file
32
 * format for further processing.
33
 */
34
class Parser
35
{
36
    /** @var string the name of the default package */
37
    protected $defaultPackageName = 'Default';
38
39
    /** @var bool whether we force a full re-parse */
40
    protected $force = false;
41
42
    /** @var bool whether to execute a PHPLint on every file */
43
    protected $validate = false;
44
45
    /** @var string[] which markers (i.e. TODO or FIXME) to collect */
46
    protected $markers = ['TODO', 'FIXME'];
47
48
    /** @var string[] which tags to ignore */
49
    protected $ignoredTags = [];
50
51
    /** @var string target location's root path */
52
    protected $path = '';
53
54
    /** @var LoggerInterface $logger */
55
    protected $logger;
56
57
    /** @var string The encoding in which the files are encoded */
58
    protected $encoding = 'utf-8';
59
60
    /** @var Stopwatch $stopwatch The profiling component that measures time and memory usage over time */
61
    protected $stopwatch = null;
62
63
    /**
64
     * @var ProjectFactory
65
     */
66
    private $projectFactory;
67
68
    /**
69
     * Initializes the parser.
70
     *
71
     * This constructor checks the user's PHP ini settings to detect which encoding is used by default. This encoding
72
     * is used as a default value for phpDocumentor to convert the source files that it receives.
73
     *
74
     * If no encoding is specified than 'utf-8' is assumed by default.
75
     *
76
     * @codeCoverageIgnore the ini_get call cannot be tested as setting it using ini_set has no effect.
77
     */
78
    public function __construct(ProjectFactory $projectFactory, Stopwatch $stopwatch, LoggerInterface $logger)
79
    {
80
        $defaultEncoding = ini_get('zend.script_encoding');
81
        if ($defaultEncoding) {
82
            $this->encoding = $defaultEncoding;
83
        }
84
85
        $this->projectFactory = $projectFactory;
86
        $this->stopwatch = $stopwatch;
87
        $this->logger = $logger;
88
    }
89
90
    /**
91
     * Sets whether to force a full parse run of all files.
92
     *
93
     * @param bool $forced Forces a full parse.
94
     *
95
     * @api
96
     */
97 1
    public function setForced($forced)
98
    {
99 1
        $this->force = $forced;
100 1
    }
101
102
    /**
103
     * Returns whether a full rebuild is required.
104
     *
105
     * @api
106
     *
107
     * @return bool
108
     */
109 1
    public function isForced()
110
    {
111 1
        return $this->force;
112
    }
113
114
    /**
115
     * Sets whether to run PHPLint on every file.
116
     *
117
     * PHPLint has a huge performance impact on the execution of phpDocumentor and
118
     * is thus disabled by default.
119
     *
120
     * @param bool $validate when true this file will be checked.
121
     *
122
     * @api
123
     */
124 1
    public function setValidate($validate)
125
    {
126 1
        $this->validate = $validate;
127 1
    }
128
129
    /**
130
     * Returns whether we want to run PHPLint on every file.
131
     *
132
     * @api
133
     *
134
     * @return bool
135
     */
136 1
    public function doValidation()
137
    {
138 1
        return $this->validate;
139
    }
140
141
    /**
142
     * Sets a list of markers to gather (i.e. TODO, FIXME).
143
     *
144
     * @param string[] $markers A list or markers to gather.
145
     *
146
     * @api
147
     */
148 1
    public function setMarkers(array $markers)
149
    {
150 1
        $this->markers = $markers;
151 1
    }
152
153
    /**
154
     * Returns the list of markers.
155
     *
156
     * @api
157
     *
158
     * @return string[]
159
     */
160 1
    public function getMarkers()
161
    {
162 1
        return $this->markers;
163
    }
164
165
    /**
166
     * Sets a list of tags to ignore.
167
     *
168
     * @param string[] $ignoredTags A list of tags to ignore.
169
     *
170
     * @api
171
     */
172 1
    public function setIgnoredTags(array $ignoredTags)
173
    {
174 1
        $this->ignoredTags = $ignoredTags;
175 1
    }
176
177
    /**
178
     * Returns the list of ignored tags.
179
     *
180
     * @api
181
     *
182
     * @return string[]
183
     */
184 1
    public function getIgnoredTags()
185
    {
186 1
        return $this->ignoredTags;
187
    }
188
189
    /**
190
     * Sets the base path of the files that will be parsed.
191
     *
192
     * @param string $path Must be an absolute path.
193
     *
194
     * @api
195
     */
196 1
    public function setPath($path)
197
    {
198 1
        $this->path = $path;
199 1
    }
200
201
    /**
202
     * Returns the absolute base path for all files.
203
     *
204
     * @return string
205
     */
206 1
    public function getPath()
207
    {
208 1
        return $this->path;
209
    }
210
211
    /**
212
     * Sets the name of the default package.
213
     *
214
     * @param string $defaultPackageName Name used to categorize elements
215
     *  without an @package tag.
216
     */
217 1
    public function setDefaultPackageName($defaultPackageName)
218
    {
219 1
        $this->defaultPackageName = $defaultPackageName;
220 1
    }
221
222
    /**
223
     * Returns the name of the default package.
224
     *
225
     * @return string
226
     */
227 1
    public function getDefaultPackageName()
228
    {
229 1
        return $this->defaultPackageName;
230
    }
231
232
    /**
233
     * Sets the encoding of the files.
234
     *
235
     * With this option it is possible to tell the parser to use a specific encoding to interpret the provided files.
236
     * By default this is set to UTF-8, in which case no action is taken. Any other encoding will result in the output
237
     * being converted to UTF-8 using `iconv`.
238
     *
239
     * Please note that it is recommended to provide files in UTF-8 format; this will ensure a faster performance since
240
     * no transformation is required.
241
     *
242
     * @param string $encoding
243
     */
244 1
    public function setEncoding($encoding)
245
    {
246 1
        $this->encoding = $encoding;
247 1
    }
248
249
    /**
250
     * Returns the currently active encoding.
251
     *
252
     * @return string
253
     */
254 1
    public function getEncoding()
255
    {
256 1
        return $this->encoding;
257
    }
258
259
    /**
260
     * Iterates through the given files feeds them to the builder.
261
     *
262
     * @return \phpDocumentor\Reflection\Php\Project
263
     *
264
     * @throws FilesNotFoundException if no files were found.
265
     * @api
266
     */
267
    public function parse(array $files)
268
    {
269
        $this->startTimingTheParsePhase();
270
271
        $event = PreParsingEvent::createInstance($this);
272
        assert($event instanceof PreParsingEvent);
273
        Dispatcher::getInstance()
274
            ->dispatch(
275
                'parser.pre',
276
                $event->setFileCount(count($files))
277
            );
278
279
        /** @var \phpDocumentor\Reflection\Php\Project $project */
280
        $project = $this->projectFactory->create(ProjectDescriptorBuilder::DEFAULT_PROJECT_NAME, $files);
281
        $this->logAfterParsingAllFiles();
282
283
        return $project;
284
    }
285
286
    /**
287
     * Writes the complete parsing cycle to log.
288
     */
289
    private function logAfterParsingAllFiles()
290
    {
291
        if (!$this->stopwatch) {
292
            return;
293
        }
294
295
        $event = $this->stopwatch->stop('parser.parse');
296
297
        $this->log('Elapsed time to parse all files: ' . round($event->getDuration() / 1000, 2) . 's');
298
        $this->log('Peak memory usage: ' . round($event->getMemory() / 1024 / 1024, 2) . 'M');
299
    }
300
301
    /**
302
     * Dispatches a logging request.
303
     *
304
     * @param string   $message  The message to log.
305
     * @param string   $priority The logging priority as declared in the LogLevel PSR-3 class.
306
     * @param string[] $parameters
307
     */
308
    private function log($message, $priority = LogLevel::INFO, $parameters = [])
309
    {
310
        $this->logger->log($priority, $message, $parameters);
311
    }
312
313
    private function startTimingTheParsePhase()
314
    {
315
        if ($this->stopwatch) {
316
            $this->stopwatch->start('parser.parse');
317
        }
318
    }
319
}
320