PhpSourceGenerator::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 10
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 4
1
<?php declare(strict_types=1);
2
3
namespace Stratadox\PhpGenerics\Generator;
4
5
use Doctrine\Common\Annotations\AnnotationException;
6
use Doctrine\Common\Annotations\AnnotationReader;
7
use Doctrine\Common\Annotations\AnnotationRegistry;
8
use PhpParser\NodeTraverser;
9
use PhpParser\NodeTraverserInterface;
10
use PhpParser\NodeVisitor;
11
use PhpParser\Parser;
12
use PhpParser\ParserFactory;
13
use PhpParser\PrettyPrinter\Standard as StandardAstPrinter;
14
use PhpParser\PrettyPrinterAbstract as AstPrinter;
15
use Stratadox\PhpGenerics\Generator\Type\TypeArguments;
16
17
final class PhpSourceGenerator implements SourceGenerator
18
{
19
    /** @var Parser */
20
    private $parser;
21
    /** @var AstPrinter */
22
    private $printer;
23
    /** @var SourceExtractor */
24
    private $extract;
25
    /** @var VisitorFactory */
26
    private $visitors;
27
28
    public function __construct(
29
        Parser $parser,
30
        AstPrinter $printer,
31
        SourceExtractor $extract,
32
        VisitorFactory $visitors
33
    ) {
34
        $this->parser = $parser;
35
        $this->printer = $printer;
36
        $this->extract = $extract;
37
        $this->visitors = $visitors;
38
    }
39
40
    /** @throws AnnotationException */
41
    public static function default(): self
42
    {
43
        AnnotationRegistry::registerUniqueLoader('class_exists');
0 ignored issues
show
Deprecated Code introduced by
The function Doctrine\Common\Annotati...:registerUniqueLoader() has been deprecated: this method is deprecated and will be removed in doctrine/annotations 2.0 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

43
        /** @scrutinizer ignore-deprecated */ AnnotationRegistry::registerUniqueLoader('class_exists');

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
44
        return new self(
45
            (new ParserFactory())->create(ParserFactory::PREFER_PHP7),
46
            new StandardAstPrinter(),
47
            new SourceExtractor(),
48
            new StandardVisitorFactory(new AnnotationReader())
49
        );
50
    }
51
52
    public function generate(
53
        string $namespace,
54
        string $newClassName,
55
        string $genericBaseClass,
56
        TypeArguments $typeArguments
57
    ): string {
58
        return $this->produceConcreteChildClass(
59
            $this->extract->contentsOf($genericBaseClass),
60
            new NodeTraverser(),
61
            ...$this->visitors->replacing(
62
                $namespace,
63
                $newClassName,
64
                $this->extract->reflectionOf($genericBaseClass),
65
                $typeArguments
66
            )
67
        );
68
    }
69
70
    private function produceConcreteChildClass(
71
        string $baseClassContent,
72
        NodeTraverserInterface $traverser,
73
        NodeVisitor ...$visitors
74
    ): string {
75
        foreach ($visitors as $visitor) {
76
            $traverser->addVisitor($visitor);
77
        }
78
        return '<?php '.$this->printer->prettyPrint(
79
            $traverser->traverse($this->parser->parse($baseClassContent))
0 ignored issues
show
Bug introduced by
It seems like $this->parser->parse($baseClassContent) can also be of type null; however, parameter $nodes of PhpParser\NodeTraverserInterface::traverse() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

79
            $traverser->traverse(/** @scrutinizer ignore-type */ $this->parser->parse($baseClassContent))
Loading history...
80
        );
81
    }
82
}
83