28
28
use MongoDB \Model \BSONArray ;
29
29
use Nette \PhpGenerator \ClassType ;
30
30
use Nette \PhpGenerator \Method ;
31
+ use Nette \PhpGenerator \Parameter ;
31
32
use Nette \PhpGenerator \PhpNamespace ;
32
33
use Nette \PhpGenerator \TraitType ;
33
- use RuntimeException ;
34
+ use ReflectionClass ;
34
35
use stdClass ;
35
- use Throwable ;
36
36
37
37
use function array_key_last ;
38
38
use function array_map ;
42
42
43
43
/**
44
44
* Generates a fluent factory class for aggregation pipeline stages.
45
- * The method definition is based on the manually edited static class
46
- * that imports the stage factory trait .
45
+ * The method definition is based on all the public static methods
46
+ * of the Stage class .
47
47
*/
48
48
class FluentStageFactoryGenerator extends OperatorGenerator
49
49
{
50
- /**
51
- * All public of this class are duplicated as instance methods of the
52
- * fluent factory class.
53
- */
54
50
private const FACTORY_CLASS = Stage::class;
55
51
56
52
public function generate (GeneratorDefinition $ definition ): void
@@ -98,37 +94,37 @@ private function createFluentFactoryClass(GeneratorDefinition $definition): PhpN
98
94
99
95
$ staticFactory = ClassType::from (self ::FACTORY_CLASS );
100
96
assert ($ staticFactory instanceof ClassType);
97
+
98
+ // Import the methods customized in the factory class
101
99
foreach ($ staticFactory ->getMethods () as $ method ) {
102
100
if (! $ method ->isPublic ()) {
103
101
continue ;
104
102
}
105
103
106
- try {
107
- $ this ->addMethod ($ method , $ namespace , $ class );
108
- } catch (Throwable $ e ) {
109
- throw new RuntimeException (sprintf ('Failed to generate class for operator "%s" ' , $ operator ->name ), 0 , $ e );
110
- }
104
+ $ this ->addMethod ($ method , $ class );
111
105
}
112
106
113
- $ staticFactory = TraitType::from (Stage \FactoryTrait::class);
114
- assert ($ staticFactory instanceof TraitType);
115
- foreach ($ staticFactory ->getMethods () as $ method ) {
116
- if (! $ method ->isPublic ()) {
117
- continue ;
118
- }
119
-
120
- try {
121
- $ this ->addMethod ($ method , $ namespace , $ class );
122
- } catch (Throwable $ e ) {
123
- throw new RuntimeException (sprintf ('Failed to generate class for operator "%s" ' , $ operator ->name ), 0 , $ e );
107
+ // Import the other methods provided by the generated trait
108
+ foreach ($ staticFactory ->getTraits () as $ trait ) {
109
+ $ staticFactory = TraitType::from ($ trait ->getName ());
110
+ assert ($ staticFactory instanceof TraitType);
111
+ foreach ($ staticFactory ->getMethods () as $ method ) {
112
+ $ this ->addMethod ($ method , $ class );
124
113
}
125
114
}
126
115
127
116
return $ namespace ;
128
117
}
129
118
130
- private function addMethod (Method $ factoryMethod , PhpNamespace $ namespace , ClassType $ class ): void
119
+ private function addMethod (Method $ factoryMethod , ClassType $ class ): void
131
120
{
121
+ // Non-public methods are not part of the API
122
+ if (! $ factoryMethod ->isPublic ()) {
123
+ return ;
124
+ }
125
+
126
+ // Some methods can be overridden in the class, so we skip them
127
+ // when importing the methods provided by the trait.
132
128
if ($ class ->hasMethod ($ factoryMethod ->getName ())) {
133
129
return ;
134
130
}
@@ -139,7 +135,7 @@ private function addMethod(Method $factoryMethod, PhpNamespace $namespace, Class
139
135
$ method ->setParameters ($ factoryMethod ->getParameters ());
140
136
141
137
$ args = array_map (
142
- fn ($ param ) => '$ ' . $ param ->getName (),
138
+ fn (Parameter $ param ): string => '$ ' . $ param ->getName (),
143
139
$ factoryMethod ->getParameters (),
144
140
);
145
141
@@ -155,9 +151,9 @@ private function addMethod(Method $factoryMethod, PhpNamespace $namespace, Class
155
151
156
152
return $this;
157
153
PHP,
158
- ' Stage ' ,
154
+ ( new ReflectionClass ( self :: FACTORY_CLASS ))-> getShortName () ,
159
155
$ factoryMethod ->getName (),
160
- implode (', ' , $ args ),
156
+ implode (', ' , $ args ),
161
157
));
162
158
}
163
159
}
0 commit comments