-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathcreate-app-facade
141 lines (122 loc) · 4.22 KB
/
create-app-facade
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#! /usr/bin/env php
<?php
use lucatume\DI52\Container;
require __DIR__ . '/../vendor/autoload.php';
$appFacadeSourceFile = __DIR__ . '/../src/Container.php';
$appFacadeDestFile = __DIR__ . '/../src/App.php';
$appFacadeSourceFileLines = file($appFacadeSourceFile);
if (false === $appFacadeSourceFileLines) {
echo "\nCould not open container source file ({$appFacadeSourceFile}).\n";
exit(1);
}
$extractMethodArgs = static function (ReflectionMethod $method) use ($appFacadeSourceFileLines) {
$methodLine = $method->getStartLine();
$signatureLine = $appFacadeSourceFileLines[$methodLine - 1];
$signatureLineFrags = preg_split('/[()]/', $signatureLine);
return $signatureLineFrags[1] ?? '';
};
$methodReturnsVoid = static function (ReflectionMethod $method) {
$docBlock = $method->getDocComment();
return count(
array_filter(
explode("\n", $docBlock),
static function (string $line) {
return preg_match('/@return void/', $line);
}
)
);
};
$appFacadeContentsTemplate = <<< PHP_CODE
<?php
/**
* A facade to make a DI container instance globally available as a Service Locator.
*
* @package lucatume\DI52
*/
namespace lucatume\DI52;
use lucatume\DI52\Builders\ValueBuilder;
/**
* Class App
*
* @package lucatume\DI52
*/
class App
{
/** A reference to the singleton instance of the DI container
* the application uses as Service Locator.
*
* @var Container|null
*/
protected static \$container;
/**
* Returns the singleton instance of the DI container the application
* will use as Service Locator.
*
* @return Container The singleton instance of the Container used as Service Locator
* by the application.
*/
public static function container()
{
if (!isset(static::\$container)) {
static::\$container = new Container();
}
return static::\$container;
}
/**
* Sets the container instance the Application should use as a Service Locator.
*
* If the Application already stores a reference to a Container instance, then
* this will be replaced by the new one.
*
* @param Container \$container A reference to the Container instance the Application
* should use as a Service Locator.
*
* @return void The method does not return any value.
*/
public static function setContainer(Container \$container)
{
static::\$container = \$container;
}
{{ generated_code }}
}
PHP_CODE;
$methodTemplate = <<< PHP_CODE
{{ method_doc_block }}
public static function {{ method_name }}({{ method_args }})
{
{{ method_return }}static::container()->{{ method_name }}({{ method_arg_names }});
}
PHP_CODE;
$containerClassReflection = new ReflectionClass(Container::class);
$containerPublicMethods = $containerClassReflection->getMethods(ReflectionMethod::IS_PUBLIC);
$appFacadeGenereatedCodeEntries = [];
foreach ($containerPublicMethods as $method) {
if ($method->name === '__construct') {
continue;
}
$data = [
'{{ method_doc_block }}' => (string)$method->getDocComment(),
'{{ method_return }}' => $methodReturnsVoid($method) ? '' : 'return ',
'{{ method_name }}' => $method->getName(),
'{{ method_args }}' => $extractMethodArgs($method),
'{{ method_arg_names }}' => implode(
', ',
array_map(
static function (ReflectionParameter $p) {
if($p->isVariadic()){
return '...$' . $p->getName();
}
return '$' . $p->getName();
},
$method->getParameters()
)
)
];
$methodCode = str_replace(array_keys($data), $data, $methodTemplate);
$appFacadeGenereatedCodeEntries[] = $methodCode;
}
$appFacadeGenereatedCode = implode("\n\n", $appFacadeGenereatedCodeEntries);
$appFacadeContents = str_replace('{{ generated_code }}', $appFacadeGenereatedCode, $appFacadeContentsTemplate);
if(!file_put_contents($appFacadeDestFile, $appFacadeContents)){
throw new \RuntimeException("Could not create file {$appFacadeDestFile}");
}