FileAssembler::addClasses()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 11.2817

Importance

Changes 0
Metric Value
cc 4
nc 4
nop 2
dl 0
loc 20
rs 9.6
c 0
b 0
f 0
ccs 3
cts 13
cp 0.2308
crap 11.2817
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\Descriptor\Builder\Reflector;
17
18
use phpDocumentor\Descriptor\Collection;
19
use phpDocumentor\Descriptor\FileDescriptor;
20
use phpDocumentor\Descriptor\TagDescriptor;
21
use phpDocumentor\Reflection\Php\Class_;
22
use phpDocumentor\Reflection\Php\Constant;
23
use phpDocumentor\Reflection\Php\File;
24
use phpDocumentor\Reflection\Php\Function_;
25
use phpDocumentor\Reflection\Php\Interface_;
26
use phpDocumentor\Reflection\Php\Trait_;
27
28
/**
29
 * Assembles an FileDescriptor using an FileReflector and ParamDescriptors.
30
 */
31
class FileAssembler extends AssemblerAbstract
32
{
33
    /**
34
     * Creates a Descriptor from the provided data.
35
     *
36
     * @param File $data
37
     *
38
     * @return FileDescriptor
39
     */
40 1
    public function create($data)
41
    {
42 1
        $fileDescriptor = new FileDescriptor($data->getHash());
43 1
        $fileDescriptor->setPackage(
44 1
            $this->extractPackageFromDocBlock($data->getDocBlock()) ?: $this->getBuilder()->getDefaultPackage()
0 ignored issues
show
Bug introduced by
It seems like $data->getDocBlock() can be null; however, extractPackageFromDocBlock() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
45
        );
46
47 1
        $fileDescriptor->setName($data->getName());
48 1
        $fileDescriptor->setPath($data->getPath());
49 1
        if ($this->getBuilder()->getProjectDescriptor()->getSettings()->shouldIncludeSource()) {
50 1
            $fileDescriptor->setSource($data->getSource());
51
        }
52
53 1
        $fileDescriptor->setIncludes(new Collection($data->getIncludes()));
54 1
        $fileDescriptor->setNamespaceAliases(new Collection($data->getNamespaces()));
55
56 1
        $this->assembleDocBlock($data->getDocBlock(), $fileDescriptor);
57 1
        $this->overridePackageTag($data, $fileDescriptor);
58
59
        //$this->addMarkers($data->getMarkers(), $fileDescriptor);
60 1
        $this->addConstants($data->getConstants(), $fileDescriptor);
61 1
        $this->addFunctions($data->getFunctions(), $fileDescriptor);
62 1
        $this->addClasses($data->getClasses(), $fileDescriptor);
63 1
        $this->addInterfaces($data->getInterfaces(), $fileDescriptor);
64 1
        $this->addTraits($data->getTraits(), $fileDescriptor);
65
66 1
        return $fileDescriptor;
67
    }
68
69
    /**
70
     * Registers the child constants with the generated File Descriptor.
71
     *
72
     * @param Constant[] $constants
73
     */
74 1
    protected function addConstants(array $constants, FileDescriptor $fileDescriptor): void
75
    {
76 1
        foreach ($constants as $constant) {
77
            $constantDescriptor = $this->getBuilder()->buildDescriptor($constant);
78
            if ($constantDescriptor) {
79
                $constantDescriptor->setLocation($fileDescriptor, $constant->getLocation()->getLineNumber());
80
                if (count($constantDescriptor->getTags()->get('package', new Collection())) === 0) {
81
                    $constantDescriptor->getTags()
82
                        ->set('package', $fileDescriptor->getTags()->get('package', new Collection()));
83
                }
84
85
                $fileDescriptor->getConstants()->set(
86
                    (string) $constantDescriptor->getFullyQualifiedStructuralElementName(),
87
                    $constantDescriptor
88
                );
89
            }
90
        }
91 1
    }
92
93
    /**
94
     * Registers the child functions with the generated File Descriptor.
95
     *
96
     * @param Function_[] $functions
97
     */
98 1
    protected function addFunctions(array $functions, FileDescriptor $fileDescriptor): void
99
    {
100 1
        foreach ($functions as $function) {
101
            $functionDescriptor = $this->getBuilder()->buildDescriptor($function);
102
            if ($functionDescriptor) {
103
                $functionDescriptor->setLocation($fileDescriptor, $function->getLocation()->getLineNumber());
104
                if (count($functionDescriptor->getTags()->get('package', new Collection())) === 0) {
105
                    $functionDescriptor->getTags()
106
                        ->set('package', $fileDescriptor->getTags()->get('package', new Collection()));
107
                }
108
109
                $fileDescriptor->getFunctions()->set(
110
                    (string) $functionDescriptor->getFullyQualifiedStructuralElementName(),
111
                    $functionDescriptor
112
                );
113
            }
114
        }
115 1
    }
116
117
    /**
118
     * Registers the child classes with the generated File Descriptor.
119
     *
120
     * @param Class_[] $classes
121
     */
122 1
    protected function addClasses(array $classes, FileDescriptor $fileDescriptor): void
123
    {
124 1
        foreach ($classes as $class) {
125
            $classDescriptor = $this->getBuilder()->buildDescriptor($class);
126
            if ($classDescriptor) {
127
                $classDescriptor->setLocation($fileDescriptor, $class->getLocation()->getLineNumber());
128
                if (count($classDescriptor->getTags()->get('package', new Collection())) === 0) {
129
                    $classDescriptor->getTags()->set(
130
                        'package',
131
                        $fileDescriptor->getTags()->get('package', new Collection())
132
                    );
133
                }
134
135
                $fileDescriptor->getClasses()->set(
136
                    (string) ($classDescriptor->getFullyQualifiedStructuralElementName()),
137
                    $classDescriptor
138
                );
139
            }
140
        }
141 1
    }
142
143
    /**
144
     * Registers the child interfaces with the generated File Descriptor.
145
     *
146
     * @param Interface_[] $interfaces
147
     */
148 1
    protected function addInterfaces(array $interfaces, FileDescriptor $fileDescriptor): void
149
    {
150 1
        foreach ($interfaces as $interface) {
151
            $interfaceDescriptor = $this->getBuilder()->buildDescriptor($interface);
152
            if ($interfaceDescriptor) {
153
                $interfaceDescriptor->setLocation($fileDescriptor, $interface->getLocation()->getLineNumber());
154
                if (count($interfaceDescriptor->getTags()->get('package', new Collection())) === 0) {
155
                    $interfaceDescriptor->getTags()
156
                        ->set('package', $fileDescriptor->getTags()->get('package', new Collection()));
157
                }
158
159
                $fileDescriptor->getInterfaces()->set(
160
                    (string) $interfaceDescriptor->getFullyQualifiedStructuralElementName(),
161
                    $interfaceDescriptor
162
                );
163
            }
164
        }
165 1
    }
166
167
    /**
168
     * Registers the child traits with the generated File Descriptor.
169
     *
170
     * @param Trait_[] $traits
171
     */
172 1
    protected function addTraits(array $traits, FileDescriptor $fileDescriptor): void
173
    {
174 1
        foreach ($traits as $trait) {
175
            $traitDescriptor = $this->getBuilder()->buildDescriptor($trait);
176
            if ($traitDescriptor) {
177
                $traitDescriptor->setLocation($fileDescriptor, $trait->getLocation()->getLineNumber());
178
                if (count($traitDescriptor->getTags()->get('package', new Collection())) === 0) {
179
                    $traitDescriptor->getTags()
180
                        ->set('package', $fileDescriptor->getTags()->get('package', new Collection()));
181
                }
182
183
                $fileDescriptor->getTraits()->set(
184
                    (string) $traitDescriptor->getFullyQualifiedStructuralElementName(),
185
                    $traitDescriptor
186
                );
187
            }
188
        }
189 1
    }
190
191
    /**
192
     * Registers the markers that were found in a File with the File Descriptor.
193
     *
194
     * @param string[]       $markers
195
     */
196
    protected function addMarkers(array $markers, FileDescriptor $fileDescriptor): void
197
    {
198
        foreach ($markers as $marker) {
199
            list($type, $message, $line) = $marker;
200
            $fileDescriptor->getMarkers()->add(
201
                [
202
                    'type' => $type,
203
                    'message' => $message,
204
                    'line' => $line,
205
                ]
206
            );
207
        }
208
    }
209
210 1
    protected function overridePackageTag(File $data, FileDescriptor $fileDescriptor): void
211
    {
212 1
        $packages = new Collection();
213 1
        $package = $this->extractPackageFromDocBlock($data->getDocBlock());
0 ignored issues
show
Bug introduced by
It seems like $data->getDocBlock() can be null; however, extractPackageFromDocBlock() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
214 1
        if (! $package) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $package of type null|string is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
215 1
            $package = $this->getBuilder()->getDefaultPackage();
216
        }
217
218 1
        $tag = new TagDescriptor('package');
219 1
        $tag->setDescription($package);
220 1
        $packages->add($tag);
221 1
        $fileDescriptor->getTags()->set('package', $packages);
222 1
    }
223
}
224