Passed
Pull Request — master (#22)
by Luis
24:40 queued 21:48
created

PhpCodeParser::fromConfiguration()   A

Complexity

Conditions 5
Paths 16

Size

Total Lines 44
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 33
CRAP Score 5

Importance

Changes 0
Metric Value
cc 5
eloc 34
nc 16
nop 1
dl 0
loc 44
ccs 33
cts 33
cp 1
crap 5
rs 9.0648
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
/**
3
 * PHP version 8.1
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 phpDocumentor\Reflection\DocBlockFactory;
11
use PhpParser\Node\Stmt;
12
use PhpParser\NodeTraverser;
13
use PhpParser\NodeVisitor\NameResolver;
14
use PhpParser\NodeVisitor\NodeConnectingVisitor;
15
use PhpParser\Parser;
16
use PhpParser\ParserFactory;
17
use PhUml\Code\Codebase;
18
use PhUml\Parser\Code\Builders\AttributeAnalyzer;
19
use PhUml\Parser\Code\Builders\ClassDefinitionBuilder;
20
use PhUml\Parser\Code\Builders\Filters\PrivateVisibilityFilter;
21
use PhUml\Parser\Code\Builders\Filters\ProtectedVisibilityFilter;
22
use PhUml\Parser\Code\Builders\InterfaceDefinitionBuilder;
23
use PhUml\Parser\Code\Builders\Members\NoConstantsBuilder;
24
use PhUml\Parser\Code\Builders\Members\NoMethodsBuilder;
25
use PhUml\Parser\Code\Builders\Members\NoPropertiesBuilder;
26
use PhUml\Parser\Code\Builders\Members\ParametersBuilder;
27
use PhUml\Parser\Code\Builders\Members\ParsedConstantsBuilder;
28
use PhUml\Parser\Code\Builders\Members\ParsedMethodsBuilder;
29
use PhUml\Parser\Code\Builders\Members\ParsedPropertiesBuilder;
30
use PhUml\Parser\Code\Builders\Members\TypeBuilder;
31
use PhUml\Parser\Code\Builders\Members\VisibilityBuilder;
32
use PhUml\Parser\Code\Builders\Members\VisibilityFilters;
33
use PhUml\Parser\Code\Builders\MembersBuilder;
34
use PhUml\Parser\Code\Builders\TagTypeFactory;
35
use PhUml\Parser\Code\Builders\TraitDefinitionBuilder;
36
use PhUml\Parser\Code\Builders\UseStatementsBuilder;
37
use PhUml\Parser\Code\Visitors\ClassVisitor;
38
use PhUml\Parser\Code\Visitors\InterfaceVisitor;
39
use PhUml\Parser\Code\Visitors\TraitVisitor;
40
use PhUml\Parser\CodeParserConfiguration;
41
use PhUml\Parser\SourceCode;
42
43
/**
44
 * It traverses the AST of all the files and interfaces found by the `CodeFinder` and builds a
45
 * `Codebase` object
46
 *
47
 * In order to create the collection of definitions it uses the following visitors
48
 *
49
 * - The `ClassVisitor` which builds `ClassDefinition`s
50
 * - The `InterfaceVisitor` which builds `InterfaceDefinition`s
51
 * - The `TraitVisitor` which builds `TraitDefinition`s
52
 */
53
final class PhpCodeParser
54
{
55 37
    public static function fromConfiguration(CodeParserConfiguration $configuration): PhpCodeParser
56
    {
57 37
        if ($configuration->hideAttributes()) {
58 6
            $constantsBuilder = new NoConstantsBuilder();
59 6
            $propertiesBuilder = new NoPropertiesBuilder();
60
        }
61 37
        if ($configuration->hideMethods()) {
62 6
            $methodsBuilder = new NoMethodsBuilder();
63
        }
64 37
        $filters = [];
65 37
        if ($configuration->hidePrivate()) {
66 5
            $filters[] = new PrivateVisibilityFilter();
67
        }
68 37
        if ($configuration->hideProtected()) {
69 5
            $filters[] = new ProtectedVisibilityFilter();
70
        }
71 37
        $visibilityBuilder = new VisibilityBuilder();
72 37
        $typeBuilder = new TypeBuilder(new TypeResolver(new TagTypeFactory(DocBlockFactory::createInstance())));
73 37
        $methodsBuilder ??= new ParsedMethodsBuilder(
74 31
            new ParametersBuilder($typeBuilder),
75
            $typeBuilder,
76
            $visibilityBuilder,
77
        );
78 37
        $constantsBuilder ??= new ParsedConstantsBuilder($visibilityBuilder);
79 37
        $propertiesBuilder ??= new ParsedPropertiesBuilder($visibilityBuilder, $typeBuilder);
80 37
        $filters = new VisibilityFilters($filters);
81 37
        $membersBuilder = new MembersBuilder($constantsBuilder, $propertiesBuilder, $methodsBuilder, $filters);
82 37
        $useStatementsBuilder = new UseStatementsBuilder();
83 37
        $classBuilder = new ClassDefinitionBuilder($membersBuilder, $useStatementsBuilder, new AttributeAnalyzer());
84 37
        $interfaceBuilder = new InterfaceDefinitionBuilder($membersBuilder, $useStatementsBuilder);
85 37
        $traitBuilder = new TraitDefinitionBuilder($membersBuilder, $useStatementsBuilder);
86
87 37
        $codebase = new Codebase();
88
89 37
        $parser = (new ParserFactory())->create(ParserFactory::PREFER_PHP7);
90 37
        $traverser = new NodeTraverser();
91 37
        $traverser->addVisitor(new NameResolver());
92 37
        $traverser->addVisitor(new NodeConnectingVisitor());
93 37
        $traverser->addVisitor(new ClassVisitor($classBuilder, $codebase));
94 37
        $traverser->addVisitor(new InterfaceVisitor($interfaceBuilder, $codebase));
95 37
        $traverser->addVisitor(new TraitVisitor($traitBuilder, $codebase));
96 37
        $traverser = new PhpTraverser($traverser, $codebase);
97
98 37
        return new self($parser, $traverser);
99
    }
100
101 37
    private function __construct(
102
        private readonly Parser $parser,
0 ignored issues
show
Bug introduced by
A parse error occurred: Syntax error, unexpected T_STRING, expecting T_VARIABLE on line 102 at column 25
Loading history...
103
        private readonly PhpTraverser $traverser,
104
    ) {
105
    }
106
107 31
    public function parse(SourceCode $sourceCode): Codebase
108
    {
109 31
        foreach ($sourceCode->fileContents() as $code) {
110
            /** @var Stmt[] $nodes Since the parser is run in throw errors mode */
111 29
            $nodes = $this->parser->parse($code);
112 29
            $this->traverser->traverse($nodes);
113
        }
114 31
        return $this->traverser->codebase();
115
    }
116
}
117