|
12 | 12 |
|
13 | 13 | use OpenCodeModeling\CodeAst\Builder\ClassBuilder; |
14 | 14 | use OpenCodeModeling\CodeAst\Builder\ClassConstBuilder; |
| 15 | +use OpenCodeModeling\CodeAst\Builder\ClassMethodBuilder; |
| 16 | +use PhpParser\Node; |
15 | 17 | use PhpParser\NodeTraverser; |
| 18 | +use PhpParser\NodeVisitor; |
| 19 | +use PhpParser\NodeVisitorAbstract; |
16 | 20 | use PhpParser\Parser; |
17 | 21 | use PhpParser\ParserFactory; |
18 | 22 | use PhpParser\PrettyPrinter\Standard; |
@@ -462,4 +466,75 @@ final class TestClass |
462 | 466 |
|
463 | 467 | $this->assertSame($expected, $this->printer->prettyPrintFile($nodeTraverser->traverse($this->parser->parse('')))); |
464 | 468 | } |
| 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 | + } |
465 | 540 | } |
0 commit comments