Skip to content

Commit d543f5b

Browse files
committed
generate fully typed dtos
1 parent 09d550e commit d543f5b

File tree

1 file changed

+91
-78
lines changed

1 file changed

+91
-78
lines changed

src/Php/ClassGenerator.php

Lines changed: 91 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,6 @@
1717

1818
class ClassGenerator
1919
{
20-
private $strictTypes;
21-
22-
public function __construct(bool $strictTypes = false)
23-
{
24-
$this->strictTypes = $strictTypes;
25-
}
26-
2720
private function handleBody(Generator\ClassGenerator $class, PHPClass $type)
2821
{
2922
foreach ($type->getProperties() as $prop) {
@@ -48,65 +41,83 @@ private function handleValueMethod(Generator\ClassGenerator $generator, PHPPrope
4841
{
4942
$type = $prop->getType();
5043

51-
$docblock = new DocBlockGenerator('Construct');
44+
$docblock = new DocBlockGenerator();
5245
$docblock->setWordWrap(false);
5346
$paramTag = new ParamTag('value');
5447
$paramTag->setTypes(($type ? $type->getPhpType() : 'mixed'));
5548

56-
$docblock->setTag($paramTag);
5749

5850
$param = new ParameterGenerator('value');
59-
if ($type && !$type->isNativeType()) {
60-
$param->setType($type->getPhpType());
51+
$param->setDefaultValue(null);
52+
if ($type) {
53+
$param->setType('?' . $type->getPhpType());
54+
} else {
55+
$docblock->setTag($paramTag);
6156
}
6257
$method = new MethodGenerator('__construct', [
6358
$param,
6459
]);
65-
$method->setDocBlock($docblock);
60+
if ($docblock->getTags()) {
61+
$method->setDocBlock($docblock);
62+
}
6663
$method->setBody('$this->value($value);');
6764

6865
$generator->addMethodFromGenerator($method);
6966

7067
$docblock = new DocBlockGenerator('Gets or sets the inner value');
7168
$docblock->setWordWrap(false);
69+
70+
$parameter = new ParameterGenerator('value');
71+
$parameter->setVariadic(true);
72+
7273
$paramTag = new ParamTag('value');
74+
$paramTag->setDescription('if provided, allows to set the inner value');
7375
if ($type && $type instanceof PHPClassOf) {
7476
$paramTag->setTypes($type->getArg()->getType()->getPhpType() . '[]');
77+
$parameter->setType('?array');
7578
} elseif ($type) {
7679
$paramTag->setTypes($prop->getType()->getPhpType());
80+
$parameter->setType('?' . $prop->getType()->getPhpType());
81+
} else {
82+
$docblock->setTag($paramTag);
7783
}
78-
$docblock->setTag($paramTag);
7984

85+
86+
$method = new MethodGenerator('value', [$parameter]);
8087
$returnTag = new ReturnTag('mixed');
8188

8289
if ($type && $type instanceof PHPClassOf) {
8390
$returnTag->setTypes($type->getArg()->getType()->getPhpType() . '[]');
91+
$method->setReturnType('?array');
92+
$docblock->setTag($returnTag);
8493
} elseif ($type) {
85-
$returnTag->setTypes($type->getPhpType());
94+
$method->setReturnType('?' . $type->getPhpType());
95+
} else {
96+
$docblock->setTag($returnTag);
8697
}
87-
$docblock->setTag($returnTag);
98+
8899

89100
$param = new ParameterGenerator('value');
90101
$param->setDefaultValue(null);
91102

92103
if ($type && !$type->isNativeType()) {
93104
$param->setType($type->getPhpType());
94105
}
95-
$method = new MethodGenerator('value', []);
106+
96107
$method->setDocBlock($docblock);
97108

98-
$methodBody = 'if ($args = func_get_args()) {' . PHP_EOL;
99-
$methodBody .= ' $this->' . $prop->getName() . ' = $args[0];' . PHP_EOL;
109+
$methodBody = 'if ($value) {' . PHP_EOL;
110+
$methodBody .= ' $this->' . $prop->getName() . ' = $value[0];' . PHP_EOL;
100111
$methodBody .= '}' . PHP_EOL;
101112
$methodBody .= 'return $this->' . $prop->getName() . ';' . PHP_EOL;
102113
$method->setBody($methodBody);
103114

104115
$generator->addMethodFromGenerator($method);
105116

106-
$docblock = new DocBlockGenerator('Gets a string value');
117+
$docblock = new DocBlockGenerator('Gets the inner value as string');
107118
$docblock->setWordWrap(false);
108-
$docblock->setTag(new ReturnTag('string'));
109119
$method = new MethodGenerator('__toString');
120+
$method->setReturnType('string');
110121
$method->setDocBlock($docblock);
111122
$method->setBody('return strval($this->' . $prop->getName() . ');');
112123
$generator->addMethodFromGenerator($method);
@@ -125,10 +136,7 @@ private function handleSetter(Generator\ClassGenerator $generator, PHPProperty $
125136
}
126137

127138
$patramTag = new ParamTag($prop->getName());
128-
$docblock->setTag($patramTag);
129139

130-
$return = new ReturnTag('self');
131-
$docblock->setTag($return);
132140

133141
$type = $prop->getType();
134142

@@ -138,9 +146,17 @@ private function handleSetter(Generator\ClassGenerator $generator, PHPProperty $
138146
$parameter = new ParameterGenerator($prop->getName());
139147

140148
if ($type && $type instanceof PHPClassOf) {
149+
$docblock->setTag($patramTag);
141150
$patramTag->setTypes($type->getArg()
142151
->getType()->getPhpType() . '[]');
143-
$parameter->setType('array');
152+
153+
154+
if ($type->getArg()->getDefault() === []) {
155+
$parameter->setType('array');
156+
} else {
157+
$parameter->setType('?array');
158+
}
159+
144160

145161
if ($p = $type->getArg()->getType()->isSimpleType()
146162
) {
@@ -150,40 +166,28 @@ private function handleSetter(Generator\ClassGenerator $generator, PHPProperty $
150166
}
151167
} elseif ($type) {
152168
if ($type->isNativeType()) {
153-
$patramTag->setTypes($type->getPhpType());
154-
if ($this->strictTypes) {
155-
$parameter->setType($type->getPhpType());
156-
}
169+
$parameter->setType('?' . $type->getPhpType());
157170
} elseif ($p = $type->isSimpleType()) {
158171
if (($t = $p->getType()) && !$t->isNativeType()) {
159-
$patramTag->setTypes($t->getPhpType());
160172
$parameter->setType($t->getPhpType());
161173
} elseif ($t) {
162-
$patramTag->setTypes($t->getPhpType());
163-
if ($this->strictTypes) {
164-
$parameter->setType($t->getPhpType());
165-
}
174+
$parameter->setType('?' . $t->getPhpType());
166175
}
167176
} else {
168-
$patramTag->setTypes($type->getPhpType());
169177
$parameter->setType(($prop->getNullable() ? '?' : '') . $type->getPhpType());
170178
}
171179
}
172180

173-
if ($this->strictTypes && $prop->getDefault() === null) {
174-
$parameter->setDefaultValue(null);
175-
}
176-
177-
if ($prop->getNullable() && $parameter->getType()) {
178-
$parameter->setDefaultValue(null);
179-
}
180-
181181
$methodBody .= '$this->' . $prop->getName() . ' = $' . $prop->getName() . ';' . PHP_EOL;
182182
$methodBody .= 'return $this;';
183183
$method->setBody($methodBody);
184184
$method->setDocBlock($docblock);
185185
$method->setParameter($parameter);
186186

187+
if ($prop->getDefault() === null) {
188+
$method->setReturnType('static');
189+
}
190+
187191
$generator->addMethodFromGenerator($method);
188192
}
189193

@@ -199,17 +203,14 @@ private function handleGetter(Generator\ClassGenerator $generator, PHPProperty $
199203
$docblock->setLongDescription($prop->getDoc());
200204
}
201205

202-
$patramTag = new ParamTag('index', 'int|string');
203-
$docblock->setTag($patramTag);
204-
205-
$docblock->setTag(new ReturnTag('bool'));
206-
207206
$paramIndex = new ParameterGenerator('index');
207+
$paramIndex->setType('int|string');
208208

209209

210210
$method = new MethodGenerator('isset' . $inflector->classify($prop->getName()), [$paramIndex]);
211211
$method->setDocBlock($docblock);
212212
$method->setBody('return isset($this->' . $prop->getName() . '[$index]);');
213+
$method->setReturnType('bool');
213214
$generator->addMethodFromGenerator($method);
214215

215216
$docblock = new DocBlockGenerator();
@@ -219,54 +220,59 @@ private function handleGetter(Generator\ClassGenerator $generator, PHPProperty $
219220
$docblock->setLongDescription($prop->getDoc());
220221
}
221222

222-
$patramTag = new ParamTag('index', 'int|string');
223-
$docblock->setTag($patramTag);
224223
$paramIndex = new ParameterGenerator('index');
225-
226-
$docblock->setTag(new ReturnTag('void'));
224+
$paramIndex->setType('int|string');
227225

228226
$method = new MethodGenerator('unset' . $inflector->classify($prop->getName()), [$paramIndex]);
229227
$method->setDocBlock($docblock);
230228
$method->setBody('unset($this->' . $prop->getName() . '[$index]);');
229+
$method->setReturnType('void');
231230
$generator->addMethodFromGenerator($method);
232231
}
233232
// ////
234233

235234
$docblock = new DocBlockGenerator();
236235
$docblock->setWordWrap(false);
237236

238-
$docblock->setShortDescription('Gets as ' . $prop->getName());
237+
$docblock->setShortDescription('Get the ' . $prop->getName());
239238

240239
if ($prop->getDoc()) {
241240
$docblock->setLongDescription($prop->getDoc());
242241
}
243242

243+
$method = new MethodGenerator('get' . $inflector->classify($prop->getName()));
244+
$method->setDocBlock($docblock);
245+
$method->setBody('return $this->' . $prop->getName() . ';');
246+
244247
$tag = new ReturnTag('mixed');
245248
$type = $prop->getType();
246249
if ($type && $type instanceof PHPClassOf) {
247250
$tt = $type->getArg()->getType();
248251
$tag->setTypes($tt->getPhpType() . '[]');
252+
$docblock->setTag($tag);
253+
254+
255+
if ($type->getArg()->getDefault() === []) {
256+
$method->setReturnType('array');
257+
} else {
258+
$method->setReturnType('?array');
259+
}
260+
261+
249262
if ($p = $tt->isSimpleType()) {
250263
if (($t = $p->getType())) {
251-
$tag->setTypes($t->getPhpType() . '[]');
252264
}
253265
}
254266
} elseif ($type) {
255267
if ($p = $type->isSimpleType()) {
256268
if ($t = $p->getType()) {
257-
$tag->setTypes($t->getPhpType());
269+
$method->setReturnType('?' . $t->getPhpType());
258270
}
259271
} else {
260-
$tag->setTypes($type->getPhpType());
272+
$method->setReturnType('?' . $type->getPhpType());
261273
}
262274
}
263275

264-
$docblock->setTag($tag);
265-
266-
$method = new MethodGenerator('get' . $inflector->classify($prop->getName()));
267-
$method->setDocBlock($docblock);
268-
$method->setBody('return $this->' . $prop->getName() . ';');
269-
270276
$generator->addMethodFromGenerator($method);
271277
}
272278

@@ -283,15 +289,12 @@ private function handleAdder(Generator\ClassGenerator $generator, PHPProperty $p
283289
$docblock->setLongDescription($prop->getDoc());
284290
}
285291

286-
$return = new ReturnTag();
287-
$return->setTypes('self');
288-
$docblock->setTag($return);
289-
290292
$patramTag = new ParamTag($propName, $type->getArg()->getType()->getPhpType());
291293
$docblock->setTag($patramTag);
292294

293295
$inflector = InflectorFactory::create()->build();
294296
$method = new MethodGenerator('addTo' . $inflector->classify($prop->getName()));
297+
$method->setReturnType('static');
295298

296299
$parameter = new ParameterGenerator($propName);
297300
$tt = $type->getArg()->getType();
@@ -336,40 +339,50 @@ private function handleProperty(Generator\ClassGenerator $class, PHPProperty $pr
336339

337340
$class->addPropertyFromGenerator($generatedProp);
338341

339-
if ($prop->getType() && (!$prop->getType()->getNamespace() && $prop->getType()->getName() == 'array')) {
340-
// $generatedProp->setDefaultValue(array(), PropertyValueGenerator::TYPE_AUTO, PropertyValueGenerator::OUTPUT_SINGLE_LINE);
341-
}
342-
343342
$docBlock = new DocBlockGenerator();
344343
$docBlock->setWordWrap(false);
345-
$generatedProp->setDocBlock($docBlock);
346344

347-
if ($prop->getDoc()) {
348-
$docBlock->setLongDescription($prop->getDoc());
349-
}
350345
$tag = new VarTag($prop->getName(), 'mixed');
351346

352347
$type = $prop->getType();
353348

354349
if ($type && $type instanceof PHPClassOf) {
350+
351+
if ($type->getArg()->getDefault() === []) {
352+
$generatedProp->setType(Generator\TypeGenerator::fromTypeString('array'));
353+
} else {
354+
$generatedProp->setType(Generator\TypeGenerator::fromTypeString('?array'));
355+
}
356+
355357
$tt = $type->getArg()->getType();
356358
$tag->setTypes($tt->getPhpType() . '[]');
357359
if ($p = $tt->isSimpleType()) {
358360
if (($t = $p->getType())) {
359361
$tag->setTypes($t->getPhpType() . '[]');
360362
}
361363
}
362-
$generatedProp->setDefaultValue($type->getArg()->getDefault());
364+
$generatedProp->setDefaultValue($type->getArg()->getDefault(), \Laminas\Code\Generator\PropertyValueGenerator::TYPE_ARRAY, \Laminas\Code\Generator\PropertyValueGenerator::OUTPUT_SINGLE_LINE);
365+
$docBlock->setTag($tag);
363366
} elseif ($type) {
364367
if ($type->isNativeType()) {
365-
$tag->setTypes($type->getPhpType());
368+
$generatedProp->setType(Generator\TypeGenerator::fromTypeString('?' . $type->getPhpType()));
366369
} elseif (($p = $type->isSimpleType()) && ($t = $p->getType())) {
367-
$tag->setTypes($t->getPhpType());
370+
$generatedProp->setType(Generator\TypeGenerator::fromTypeString('?' . $t->getPhpType()));
368371
} else {
369-
$tag->setTypes($prop->getType()->getPhpType());
372+
$generatedProp->setType(Generator\TypeGenerator::fromTypeString('?' . $prop->getType()->getPhpType()));
370373
}
374+
} else {
375+
$docBlock->setTag($tag);
371376
}
372-
$docBlock->setTag($tag);
377+
378+
if ($prop->getDoc()) {
379+
$docBlock->setLongDescription($prop->getDoc());
380+
}
381+
382+
if ($prop->getDoc() || $docBlock->getTags()) {
383+
$generatedProp->setDocBlock($docBlock);
384+
}
385+
373386
}
374387

375388
public function generate(PHPClass $type)

0 commit comments

Comments
 (0)