Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 0152269

Browse files
Support custom node visitors in class and interface builder - Close #65
1 parent e2f0df5 commit 0152269

File tree

3 files changed

+107
-2
lines changed

3 files changed

+107
-2
lines changed

‎src/Builder/ClassBuilder.php

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ final class ClassBuilder implements File
6464
/** @var ClassMethodBuilder[] */
6565
private array $methods = [];
6666

67+
/** @var NodeVisitor[] */
68+
private array $nodeVisitors = [];
69+
6770
private function __construct()
6871
{
6972
}
@@ -414,6 +417,18 @@ public function hasMethod(string $methodName): bool
414417
return isset($this->methods[$methodName]);
415418
}
416419

420+
public function setNodeVisitors(NodeVisitor ...$nodeVisitors): void
421+
{
422+
$this->nodeVisitors = $nodeVisitors;
423+
}
424+
425+
public function addNodeVisitor(NodeVisitor ...$nodeVisitors): void
426+
{
427+
foreach ($nodeVisitors as $nodeVisitor) {
428+
$this->nodeVisitors[] = $nodeVisitor;
429+
}
430+
}
431+
417432
public function getNamespace(): ?string
418433
{
419434
return $this->namespace;
@@ -649,7 +664,7 @@ static function (ClassMethodBuilder $method) use ($parser) {
649664
);
650665
}
651666

652-
return $visitors;
667+
return \array_merge($visitors, $this->nodeVisitors);
653668
}
654669

655670
private function unpackNode(Node $node): void

‎src/Builder/InterfaceBuilder.php

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ final class InterfaceBuilder implements File
4747
/** @var ClassMethodBuilder[] */
4848
private array $methods = [];
4949

50+
/** @var NodeVisitor[] */
51+
private array $nodeVisitors = [];
52+
5053
private function __construct()
5154
{
5255
}
@@ -265,6 +268,18 @@ public function hasMethod(string $methodName): bool
265268
return isset($this->methods[$methodName]);
266269
}
267270

271+
public function setNodeVisitors(NodeVisitor ...$nodeVisitors): void
272+
{
273+
$this->nodeVisitors = $nodeVisitors;
274+
}
275+
276+
public function addNodeVisitor(NodeVisitor ...$nodeVisitors): void
277+
{
278+
foreach ($nodeVisitors as $nodeVisitor) {
279+
$this->nodeVisitors[] = $nodeVisitor;
280+
}
281+
}
282+
268283
/**
269284
* Uses uasort internally
270285
*
@@ -402,7 +417,7 @@ static function (ClassMethodBuilder $method) use ($parser) {
402417
);
403418
}
404419

405-
return $visitors;
420+
return \array_merge($visitors, $this->nodeVisitors);
406421
}
407422

408423
private function unpackNode(Node $node): void

‎tests/Builder/ClassBuilderTest.php

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@
1212

1313
use OpenCodeModeling\CodeAst\Builder\ClassBuilder;
1414
use OpenCodeModeling\CodeAst\Builder\ClassConstBuilder;
15+
use OpenCodeModeling\CodeAst\Builder\ClassMethodBuilder;
16+
use PhpParser\Node;
1517
use PhpParser\NodeTraverser;
18+
use PhpParser\NodeVisitor;
19+
use PhpParser\NodeVisitorAbstract;
1620
use PhpParser\Parser;
1721
use PhpParser\ParserFactory;
1822
use PhpParser\PrettyPrinter\Standard;
@@ -462,4 +466,75 @@ final class TestClass
462466

463467
$this->assertSame($expected, $this->printer->prettyPrintFile($nodeTraverser->traverse($this->parser->parse(''))));
464468
}
469+
470+
/**
471+
* @test
472+
*/
473+
public function it_supports_adding_of_node_visitors(): void
474+
{
475+
$ast = $this->parser->parse('');
476+
477+
$classFactory = ClassBuilder::fromScratch('TestClass', 'My\\Awesome\\Service');
478+
$classFactory->setMethods(
479+
ClassMethodBuilder::fromScratch('setActive')->setReturnType('void')->setStatic(true)
480+
);
481+
482+
$classFactory->addNodeVisitor($this->getSetActiveNodeVisitor());
483+
484+
$nodeTraverser = new NodeTraverser();
485+
$classFactory->injectVisitors($nodeTraverser, $this->parser);
486+
487+
$expected = <<<'EOF'
488+
<?php
489+
490+
declare (strict_types=1);
491+
namespace My\Awesome\Service;
492+
493+
class TestClass
494+
{
495+
public static function setActive() : void
496+
{
497+
$tmp = $this->get();
498+
}
499+
}
500+
EOF;
501+
502+
$this->assertSame($expected, $this->printer->prettyPrintFile($nodeTraverser->traverse($ast)));
503+
}
504+
505+
private function getSetActiveNodeVisitor(): NodeVisitor
506+
{
507+
$nodes = $this->parser->parse('<?php $tmp = $this->get();');
508+
509+
return new class($nodes) extends NodeVisitorAbstract {
510+
private $nodes;
511+
512+
public function __construct($nodes)
513+
{
514+
$this->nodes = $nodes;
515+
}
516+
517+
public function afterTraverse(array $nodes)
518+
{
519+
$newNodes = [];
520+
521+
foreach ($nodes as $node) {
522+
$newNodes[] = $node;
523+
524+
if (! $node instanceof Node\Stmt\Class_) {
525+
continue;
526+
}
527+
528+
if ($node->stmts[0] instanceof Node\Stmt\ClassMethod
529+
&& $node->stmts[0]->name instanceof Node\Identifier
530+
&& $node->stmts[0]->name->name === 'setActive'
531+
) {
532+
$node->stmts[0]->stmts = $this->nodes;
533+
}
534+
}
535+
536+
return $newNodes;
537+
}
538+
};
539+
}
465540
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /