Completed
Push — develop ( a89061...54507c )
by Jaap
08:53
created

src/phpDocumentor/Application/Stage/Parser.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * This file is part of phpDocumentor.
4
 *
5
 *  For the full copyright and license information, please view the LICENSE
6
 *  file that was distributed with this source code.
7
 *
8
 *  @copyright 2010-2017 Mike van Riel<[email protected]>
9
 *  @license   http://www.opensource.org/licenses/mit-license.php MIT
10
 *  @link      http://phpdoc.org
11
 */
12
13
namespace phpDocumentor\Application\Stage;
14
15
use phpDocumentor\Descriptor\Cache\ProjectDescriptorMapper;
16
use phpDocumentor\Descriptor\ProjectDescriptor;
17
use phpDocumentor\Descriptor\ProjectDescriptorBuilder;
18
use phpDocumentor\DomainModel\Parser\FileCollector;
19
use phpDocumentor\Event\LogEvent;
20
use phpDocumentor\Parser\Parser as DocParser;
21
use phpDocumentor\Partials\Collection as PartialsCollection;
22
use phpDocumentor\Reflection\DocBlock\ExampleFinder;
23
use Psr\Log\LogLevel;
24
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
25
use Zend\Cache\Storage\StorageInterface;
26
27
/**
28
 * Parses the given source code and creates a structure file.
29
 *
30
 * The parse task uses the source files defined either by -f or -d options and
31
 * generates a structure file (structure.xml) at the target location (which is
32
 * the folder 'output' unless the option -t is provided).
33
 */
34
final class Parser
35
{
36
    /** @var ProjectDescriptorBuilder $builder */
37
    private $builder;
38
39
    /** @var DocParser $parser */
40
    private $parser;
41
42
    /** @var StorageInterface */
43
    private $cache;
44
45
    /**
46
     * @var ExampleFinder
47
     */
48
    private $exampleFinder;
49
50
    /**
51
     * @var PartialsCollection
52
     */
53
    private $partials;
54
55
    /**
56
     * @var FileCollector
57
     */
58
    private $fileCollector;
59
60
    /**
61
     * @var EventDispatcherInterface
62
     */
63
    private $eventDispatcher;
64
65
    /**
66
     * ParseCommand constructor.
67
     */
68
    public function __construct(
69
        ProjectDescriptorBuilder $builder,
70
        DocParser $parser,
71
        FileCollector $fileCollector,
72
        StorageInterface $cache,
73
        ExampleFinder $exampleFinder,
74
        PartialsCollection $partials,
75
        EventDispatcherInterface $eventDispatcher
76
    ) {
77
        $this->builder = $builder;
78
        $this->parser = $parser;
79
        $this->cache = $cache;
80
        $this->exampleFinder = $exampleFinder;
81
        $this->partials = $partials;
82
        $this->fileCollector = $fileCollector;
83
        $this->eventDispatcher = $eventDispatcher;
84
    }
85
86
    private function getBuilder(): ProjectDescriptorBuilder
87
    {
88
        return $this->builder;
89
    }
90
91
    private function getParser(): DocParser
92
    {
93
        return $this->parser;
94
    }
95
96
    /**
97
     * Returns the Cache.
98
     *
99
     * @throws \InvalidArgumentException
100
     */
101
    private function getCache(): StorageInterface
102
    {
103
        return $this->cache;
104
    }
105
106
    /**
107
     * Executes the business logic involved with this command.
108
     *
109
     * @return array
110
     * @throws \Exception if the target location is not a folder.
111
     */
112
    public function __invoke(array $configuration)
113
    {
114
        //Grep only the first version for now. Multi version support will be added later
115
        $version = current($configuration['phpdocumentor']['versions']);
116
117
        //We are currently in the parser stage so grep the api config.
118
        //And for now we support a single api definition. Could be more in the future.
119
        $apiConfig = $version['api'][0];
120
121
        $parser = $this->getParser();
122
        $parser->setForced(!$configuration['phpdocumentor']['use-cache']);
123
        $parser->setEncoding($apiConfig['encoding']);
124
        $parser->setMarkers($apiConfig['markers']);
125
        $parser->setIgnoredTags($apiConfig['ignore-tags']);
126
        $parser->setValidate($apiConfig['validate']);
127
        $parser->setDefaultPackageName($apiConfig['default-package-name']);
128
129
        $builder = $this->getBuilder();
130
        $builder->createProjectDescriptor();
131
        $projectDescriptor = $builder->getProjectDescriptor();
132
        $projectDescriptor->setName($configuration['phpdocumentor']['title']);
133
        $projectDescriptor->setPartials($this->partials);
134
135
        $visibility = $this->getVisibility($apiConfig);
0 ignored issues
show
Are you sure the assignment to $visibility is correct as $this->getVisibility($apiConfig) (which targets phpDocumentor\Applicatio...Parser::getVisibility()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
136
        $projectDescriptor->getSettings()->setVisibility($visibility);
137
138
        $mapper = new ProjectDescriptorMapper($this->getCache());
139
140
        if ($configuration['phpdocumentor']['use-cache']) {
141
            //TODO: Re-enable garbage collection here.
142
            //$mapper->garbageCollect($files);
143
            $mapper->populate($projectDescriptor);
144
        }
145
146
        //TODO: Should determine root based on filesystems. Could be an issue for multiple.
147
        // Need some config update here.
148
        $this->exampleFinder->setSourceDirectory(getcwd());
149
        $this->exampleFinder->setExampleDirectories(['.']);
150
151
        $this->log('PPCPP:LOG-COLLECTING');
152
        $files = $this->getFileCollection($apiConfig);
153
        $this->log('PPCPP:LOG-OK');
154
        $this->log('PPCPP:LOG-INITIALIZING');
155
156
        $this->log('PPCPP:LOG-OK');
157
        $this->log('PPCPP:LOG-PARSING');
158
159
        $parser->parse($builder, $files);
160
161
        $this->log('PPCPP:LOG-STORECACHE', LogLevel::INFO);
162
        $projectDescriptor->getSettings()->clearModifiedFlag();
163
        $mapper->save($projectDescriptor);
164
        $this->log('PPCPP:LOG-OK');
165
166
        return $configuration;
167
    }
168
169
    /**
170
     * Returns the collection of files based on the input and configuration.
171
     */
172
    private function getFileCollection(array $apiConfig): array
173
    {
174
        $ignorePaths = array_map(
175
            function ($value) {
176
                if (substr($value, -1) === '*') {
177
                    return substr($value, 0, -1);
178
                }
179
180
                return $value;
181
            },
182
            $apiConfig['ignore']['paths']
183
        );
184
185
        return $this->fileCollector->getFiles(
186
            $apiConfig['source']['dsn'],
187
            $apiConfig['source']['paths'],
188
            [
189
                'paths' => $ignorePaths,
190
                'hidden' => $apiConfig['ignore']['hidden'],
191
            ],
192
            $apiConfig['extensions']
193
        );
194
    }
195
196
    private function getVisibility(array $apiConfig): ?int
197
    {
198
        $visibilities = $apiConfig['visibility'];
199
        $visibility = null;
200
        foreach ($visibilities as $item) {
201
            switch ($item) {
202
                case 'public':
203
                    $visibility |= ProjectDescriptor\Settings::VISIBILITY_PUBLIC;
204
                    break;
205
                case 'protected':
206
                    $visibility |= ProjectDescriptor\Settings::VISIBILITY_PROTECTED;
207
                    break;
208
                case 'private':
209
                    $visibility |= ProjectDescriptor\Settings::VISIBILITY_PRIVATE;
210
                    break;
211
            }
212
        }
213
        return $visibility;
214
    }
215
216
    /**
217
     * Dispatches a logging request.
218
     *
219
     * @param string   $message  The message to log.
220
     * @param string   $priority The logging priority as declared in the LogLevel PSR-3 class.
221
     * @param string[] $parameters
222
     */
223
    private function log($message, $priority = LogLevel::INFO, $parameters = [])
224
    {
225
        $this->eventDispatcher->dispatch(
226
            'system.log',
227
            LogEvent::createInstance($this)
228
                ->setContext($parameters)
229
                ->setMessage($message)
230
                ->setPriority($priority)
231
        );
232
    }
233
}
234