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'); |
|
|
|
|
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)) |
|
|
|
|
80
|
|
|
); |
81
|
|
|
} |
82
|
|
|
} |
83
|
|
|
|
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.