-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPhpFile.php
More file actions
123 lines (90 loc) · 2.55 KB
/
PhpFile.php
File metadata and controls
123 lines (90 loc) · 2.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
<?php
declare(strict_types=1);
namespace Auroro\Code;
final class PhpFile
{
private ?string $docblock = null;
private ?string $namespace = null;
/** @var list<string> */
private array $uses = [];
private ?string $body = null;
private mixed $returnValue = null;
private bool $hasReturn = false;
public function __construct(
private readonly Exporter $exporter = new Exporter(),
) {}
public function docblock(string $docblock): self
{
$this->docblock = $docblock;
return $this;
}
public function namespace(string $namespace): self
{
$this->namespace = $namespace;
return $this;
}
public function use(string ...$classes): self
{
foreach ($classes as $class) {
$this->uses[] = ltrim($class, '\\');
}
return $this;
}
/**
* Set the file to return a value (generates `return <exported>;`).
*/
public function return(mixed $value): self
{
$this->returnValue = $value;
$this->hasReturn = true;
return $this;
}
/**
* Set raw PHP code as the file body.
*/
public function body(string $code): self
{
$this->body = $code;
return $this;
}
public function generate(): string
{
$lines = ["<?php\n"];
if (null !== $this->docblock) {
$lines[] = $this->formatDocblock($this->docblock) . "\n";
}
$lines[] = "declare(strict_types=1);\n";
if (null !== $this->namespace) {
$lines[] = 'namespace ' . $this->namespace . ";\n";
}
if ([] !== $this->uses) {
$uses = array_unique($this->uses);
sort($uses);
foreach ($uses as $use) {
$lines[] = 'use ' . $use . ';';
}
$lines[] = '';
}
if (null !== $this->body) {
$lines[] = $this->body;
}
if ($this->hasReturn) {
$this->exporter->import(...$this->uses);
$lines[] = 'return ' . $this->exporter->export($this->returnValue) . ';';
}
$lines[] = '';
return implode("\n", $lines);
}
private function formatDocblock(string $text): string
{
$lines = explode("\n", $text);
if (1 === \count($lines)) {
return '/** ' . $lines[0] . ' */';
}
$result = "/**\n";
foreach ($lines as $line) {
$result .= '' === $line ? " *\n" : ' * ' . $line . "\n";
}
return $result . ' */';
}
}