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

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

Check that return values of null are not assigned.

Bug Minor

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