Passed
Push — union-types ( b56600 )
by Luis
14:03
created

PhpCodeParser::fromConfiguration()   A

Complexity

Conditions 5
Paths 16

Size

Total Lines 37
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 28
c 0
b 0
f 0
nc 16
nop 1
dl 0
loc 37
rs 9.1608
1
<?php declare(strict_types=1);
2
/**
3
 * PHP version 7.4
4
 *
5
 * This source file is subject to the license that is bundled with this package in the file LICENSE.
6
 */
7
8
namespace PhUml\Parser\Code;
9
10
use PhpParser\Node\Stmt;
0 ignored issues
show
Bug introduced by
The type PhpParser\Node\Stmt was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
11
use PhpParser\Parser;
0 ignored issues
show
Bug introduced by
The type PhpParser\Parser was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
12
use PhpParser\ParserFactory;
0 ignored issues
show
Bug introduced by
The type PhpParser\ParserFactory was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
13
use PhUml\Code\Codebase;
14
use PhUml\Parser\Code\Builders\ClassDefinitionBuilder;
15
use PhUml\Parser\Code\Builders\Filters\PrivateVisibilityFilter;
16
use PhUml\Parser\Code\Builders\Filters\ProtectedVisibilityFilter;
17
use PhUml\Parser\Code\Builders\InterfaceDefinitionBuilder;
18
use PhUml\Parser\Code\Builders\Members\FilteredAttributesBuilder;
19
use PhUml\Parser\Code\Builders\Members\FilteredConstantsBuilder;
20
use PhUml\Parser\Code\Builders\Members\FilteredMethodsBuilder;
21
use PhUml\Parser\Code\Builders\Members\NoAttributesBuilder;
22
use PhUml\Parser\Code\Builders\Members\NoConstantsBuilder;
23
use PhUml\Parser\Code\Builders\Members\NoMethodsBuilder;
24
use PhUml\Parser\Code\Builders\Members\ParametersBuilder;
25
use PhUml\Parser\Code\Builders\Members\TypeBuilder;
26
use PhUml\Parser\Code\Builders\Members\VisibilityBuilder;
27
use PhUml\Parser\Code\Builders\Members\VisibilityFilters;
28
use PhUml\Parser\Code\Builders\MembersBuilder;
29
use PhUml\Parser\Code\Builders\TraitDefinitionBuilder;
30
use PhUml\Parser\CodeFinder;
31
use PhUml\Parser\CodeParserConfiguration;
32
use PhUml\Parser\SourceCode;
33
34
/**
35
 * It traverses the AST of all the files and interfaces found by the `CodeFinder` and builds a
36
 * `Codebase` object
37
 *
38
 * In order to create the collection of definitions it uses the following visitors
39
 *
40
 * - The `ClassVisitor` which builds `ClassDefinition`s
41
 * - The `InterfaceVisitor` which builds `InterfaceDefinition`s
42
 * - The `TraitVisitor` which builds `TraitDefinition`s
43
 */
44
final class PhpCodeParser
45
{
46
    private Parser $parser;
47
48
    private PhpTraverser $traverser;
49
50
    public static function fromConfiguration(CodeParserConfiguration $configuration): PhpCodeParser
51
    {
52
        if ($configuration->hideAttributes()) {
53
            $constantsBuilder = new NoConstantsBuilder();
54
            $attributesBuilder = new NoAttributesBuilder();
55
        }
56
        if ($configuration->hideMethods()) {
57
            $methodsBuilder = new NoMethodsBuilder();
58
        }
59
        $filters = [];
60
        if ($configuration->hidePrivate()) {
61
            $filters[] = new PrivateVisibilityFilter();
62
        }
63
        if ($configuration->hideProtected()) {
64
            $filters[] = new ProtectedVisibilityFilter();
65
        }
66
        $visibilityBuilder = new VisibilityBuilder();
67
        $typeBuilder = new TypeBuilder();
68
        $filters = new VisibilityFilters($filters);
69
        $methodsBuilder ??= new FilteredMethodsBuilder(
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $methodsBuilder does not seem to be defined for all execution paths leading up to this point.
Loading history...
70
            new ParametersBuilder($typeBuilder),
71
            $typeBuilder,
72
            $visibilityBuilder,
73
            $filters
74
        );
75
        $constantsBuilder ??= new FilteredConstantsBuilder($visibilityBuilder, $filters);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $constantsBuilder does not seem to be defined for all execution paths leading up to this point.
Loading history...
76
        $attributesBuilder ??= new FilteredAttributesBuilder(
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $attributesBuilder does not seem to be defined for all execution paths leading up to this point.
Loading history...
77
            $visibilityBuilder,
78
            $typeBuilder,
79
            $filters
80
        );
81
        $membersBuilder = new MembersBuilder($constantsBuilder, $attributesBuilder, $methodsBuilder);
82
83
        return new PhpCodeParser(
84
            new ClassDefinitionBuilder($membersBuilder),
85
            new InterfaceDefinitionBuilder($membersBuilder),
86
            new TraitDefinitionBuilder($membersBuilder)
87
        );
88
    }
89
90
    private function __construct(
91
        ClassDefinitionBuilder $classBuilder = null,
92
        InterfaceDefinitionBuilder $interfaceBuilder = null,
93
        TraitDefinitionBuilder $traitBuilder = null
94
    ) {
95
        $this->parser = (new ParserFactory())->create(ParserFactory::PREFER_PHP7);
96
        $this->traverser = new PhpTraverser(
97
            $classBuilder ?? new ClassDefinitionBuilder(),
98
            $interfaceBuilder ?? new InterfaceDefinitionBuilder(),
99
            $traitBuilder ?? new TraitDefinitionBuilder()
100
        );
101
    }
102
103
    public function parse(SourceCode $sourceCode): Codebase
104
    {
105
        foreach ($sourceCode->fileContents() as $code) {
106
            /** @var Stmt[] $nodes Since the parser is run in throw errors mode */
107
            $nodes = $this->parser->parse($code);
108
            $this->traverser->traverse($nodes);
109
        }
110
        return $this->traverser->codebase();
111
    }
112
}
113