Skip to content

Commit 7673930

Browse files
committed
Add FileCollection filter and visit methods - close #76
1 parent 897cded commit 7673930

File tree

3 files changed

+138
-14
lines changed

3 files changed

+138
-14
lines changed

src/Builder/FileCollection.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,15 @@ static function (File $file) use ($filter) {
9393
);
9494
}
9595

96+
public function visit(callable $visitor): self
97+
{
98+
foreach ($this->items as $file) {
99+
($visitor)($file);
100+
}
101+
102+
return $this;
103+
}
104+
96105
/**
97106
* @return array<string, File>
98107
*/

src/FileCodeGenerator.php

Lines changed: 63 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ public function generateFiles(
9595
}
9696

9797
/**
98+
* @deprecated Use addPropertiesGetterMethods
99+
*
98100
* Generation of getter methods. Use $skip callable to skip generation e. g. for value objects
99101
*
100102
* @param FileCollection $classBuilderCollection Only ClassBuilder objects are considered
@@ -115,28 +117,45 @@ public function addGetterMethodsForProperties(
115117
}
116118

117119
foreach ($classBuilderCollection as $classBuilder) {
118-
if (! $classBuilder instanceof ClassBuilder) {
120+
if (! $classBuilder instanceof ClassBuilder
121+
|| true === ($skip)($classBuilder)
122+
) {
119123
continue;
120124
}
121-
foreach ($classBuilder->getProperties() as $classPropertyBuilder) {
122-
$methodName = ($methodNameFilter)($classPropertyBuilder->getName());
125+
$this->addPropertiesGetterMethods($classBuilder, $typed, $methodNameFilter);
126+
}
127+
}
123128

124-
if (true === ($skip)($classBuilder)
125-
|| $classBuilder->hasMethod($methodName)
126-
) {
127-
continue 2;
128-
}
129-
$classBuilder->addMethod(
130-
ClassMethodBuilder::fromScratch($methodName, $typed)
131-
->setReturnType($classPropertyBuilder->getType())
132-
->setReturnTypeDocBlockHint($classPropertyBuilder->getTypeDocBlockHint())
133-
->setBody('return $this->' . $classPropertyBuilder->getName() . ';')
134-
);
129+
/**
130+
* Generation of getter methods.
131+
*
132+
* @param ClassBuilder $classBuilder
133+
* @param bool $typed Should the generated code be typed
134+
* @param callable $methodNameFilter Filter the property name to your desired method name e.g. with "get" prefix
135+
*/
136+
public function addPropertiesGetterMethods(
137+
ClassBuilder $classBuilder,
138+
bool $typed,
139+
callable $methodNameFilter
140+
): void {
141+
foreach ($classBuilder->getProperties() as $classPropertyBuilder) {
142+
$methodName = ($methodNameFilter)($classPropertyBuilder->getName());
143+
144+
if ($classBuilder->hasMethod($methodName)) {
145+
continue;
135146
}
147+
$classBuilder->addMethod(
148+
ClassMethodBuilder::fromScratch($methodName, $typed)
149+
->setReturnType($classPropertyBuilder->getType())
150+
->setReturnTypeDocBlockHint($classPropertyBuilder->getTypeDocBlockHint())
151+
->setBody('return $this->' . $classPropertyBuilder->getName() . ';')
152+
);
136153
}
137154
}
138155

139156
/**
157+
* @deprecated Use addPropertiesClassConstants
158+
*
140159
* Generation of constants for each property. Use $skip callable to skip generation e. g. for value objects
141160
*
142161
* @param FileCollection $fileCollection Only ClassBuilder objects are considered
@@ -180,4 +199,34 @@ public function addClassConstantsForProperties(
180199
}
181200
}
182201
}
202+
203+
/**
204+
* Generation of constants for each property.
205+
*
206+
* @param ClassBuilder $classBuilder
207+
* @param callable $constantNameFilter Converts the name to a proper class constant name
208+
* @param callable $constantValueFilter Converts the name to a proper class constant value e.g. snake_case or camelCase
209+
* @param int $visibility Visibility of the class constant
210+
*/
211+
public function addPropertiesClassConstants(
212+
ClassBuilder $classBuilder,
213+
callable $constantNameFilter,
214+
callable $constantValueFilter,
215+
int $visibility = ClassConstGenerator::FLAG_PUBLIC
216+
): void {
217+
foreach ($classBuilder->getProperties() as $classPropertyBuilder) {
218+
$constantName = ($constantNameFilter)($classPropertyBuilder->getName());
219+
220+
if ($classBuilder->hasConstant($constantName)) {
221+
continue;
222+
}
223+
$classBuilder->addConstant(
224+
ClassConstBuilder::fromScratch(
225+
$constantName,
226+
($constantValueFilter)($classPropertyBuilder->getName()),
227+
$visibility
228+
)
229+
);
230+
}
231+
}
183232
}

tests/FileCodeGeneratorTest.php

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,4 +319,70 @@ public function bar() : bool
319319
$this->assertSame($expectedTestClass, $files['/service/src/TestClass.php']);
320320
$this->assertSame($expectedTestClassOther, $files['/service/src/TestClassOther.php']);
321321
}
322+
323+
/**
324+
* @test
325+
*/
326+
public function it_add_getter_methods_for_properties_via_visit(): void
327+
{
328+
$testClass = ClassBuilder::fromScratch('TestClass', 'MyService')
329+
->setFinal(true)
330+
->addProperty(
331+
ClassPropertyBuilder::fromScratch('foo', 'string'),
332+
ClassPropertyBuilder::fromScratch('bar', 'int'),
333+
);
334+
335+
$testClassOther = ClassBuilder::fromScratch('TestClassOther', 'MyService')
336+
->setFinal(true)
337+
->addProperty(
338+
ClassPropertyBuilder::fromScratch('foo', 'float'),
339+
ClassPropertyBuilder::fromScratch('bar', 'bool'),
340+
);
341+
342+
$expectedTestClass = <<<'EOF'
343+
<?php
344+
345+
declare (strict_types=1);
346+
namespace MyService;
347+
348+
final class TestClass
349+
{
350+
private string $foo;
351+
private int $bar;
352+
}
353+
EOF;
354+
355+
$expectedTestClassOther = <<<'EOF'
356+
<?php
357+
358+
declare (strict_types=1);
359+
namespace MyService;
360+
361+
final class TestClassOther
362+
{
363+
private float $foo;
364+
private bool $bar;
365+
public function foo() : float
366+
{
367+
return $this->foo;
368+
}
369+
public function bar() : bool
370+
{
371+
return $this->bar;
372+
}
373+
}
374+
EOF;
375+
376+
$fileCollection = FileCollection::fromItems($testClass, $testClassOther);
377+
378+
$fileCollection->filter(fn (ClassBuilder $classBuilder) => $classBuilder->getName() === 'TestClassOther')
379+
->visit(fn (ClassBuilder $classBuilder) => $this->fileCodeGenerator->addPropertiesGetterMethods($classBuilder, true, FilterFactory::methodNameFilter()));
380+
381+
$files = $this->fileCodeGenerator->generateFiles($fileCollection);
382+
383+
$this->assertArrayHasKey('/service/src/TestClassOther.php', $files);
384+
$this->assertArrayHasKey('/service/src/TestClass.php', $files);
385+
$this->assertSame($expectedTestClass, $files['/service/src/TestClass.php']);
386+
$this->assertSame($expectedTestClassOther, $files['/service/src/TestClassOther.php']);
387+
}
322388
}

0 commit comments

Comments
 (0)