Skip to content

Commit 53c2cbb

Browse files
authored
Merge pull request #5 from johnbillion/custom-visitor
2 parents acf0f06 + cb070a7 commit 53c2cbb

File tree

4 files changed

+30
-5
lines changed

4 files changed

+30
-5
lines changed

src/GenerateStubsCommand.php

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ public function configure(): void
5959
->addOption('out', null, InputOption::VALUE_REQUIRED, 'Path to a file to write pretty-printed stubs to. If unset, stubs will be written to stdout.')
6060
->addOption('force', null, InputOption::VALUE_NONE, 'Whether to force an overwrite.')
6161
->addOption('finder', null, InputOption::VALUE_REQUIRED, 'Path to a PHP file which returns a `Symfony\Finder` instance including the set of files that should be parsed. Can be used instead of, but not in addition to, passing sources directly.')
62+
->addOption('visitor', null, InputOption::VALUE_REQUIRED, 'Path to a PHP file which returns a `StubsGenerator\NodeVisitor` instance to replace the default node visitor.')
6263
->addOption('header', null, InputOption::VALUE_REQUIRED, 'A doc comment to prepend to the top of the generated stubs file. (Will be added below the opening `<?php` tag.)', '')
6364
->addOption('nullify-globals', null, InputOption::VALUE_NONE, 'Initialize all global variables with a value of `null`, instead of their assigned value.')
6465
->addOption('stats', null, InputOption::VALUE_NONE, 'Whether to print stats instead of outputting stubs. Stats will always be printed if --out is provided.');
@@ -95,13 +96,30 @@ protected function interact(InputInterface $input, OutputInterface $output): voi
9596
protected function execute(InputInterface $input, OutputInterface $output): int
9697
{
9798
$io = new SymfonyStyle($input, $output);
99+
$visitor = null;
100+
$visitorPath = $input->getOption('visitor');
101+
102+
if ($visitorPath) {
103+
$visitorPath = $this->resolvePath($visitorPath);
104+
if (!$this->filesystem->exists($visitorPath) || is_dir($visitorPath)) {
105+
throw new InvalidArgumentException("Bad --visitor path: '$visitorPath' does not exist or is a directory.");
106+
}
107+
try {
108+
$visitor = @include $visitorPath;
109+
} catch (Exception $e) {
110+
throw new RuntimeException("Could not resolve a `StubsGenerator\NodeVisitor` from '$visitorPath'.", 0, $e);
111+
}
112+
if (!$visitor || !($visitor instanceof NodeVisitor)) {
113+
throw new RuntimeException("Could not resolve a `StubsGenerator\NodeVisitor` from '$visitorPath'.");
114+
}
115+
}
98116

99117
$finder = $this->parseSources($input);
100118
$generator = new StubsGenerator($this->parseSymbols($input), [
101119
'nullify_globals' => $input->getOption('nullify-globals'),
102120
]);
103121

104-
$result = $generator->generate($finder);
122+
$result = $generator->generate($finder, $visitor);
105123

106124
$printer = new Standard();
107125

src/NodeVisitor.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ class NodeVisitor extends NodeVisitorAbstract
9090
/**
9191
* @param int $symbols Set of symbol types to include stubs for.
9292
*/
93-
public function __construct(int $symbols = StubsGenerator::DEFAULT, array $config = [])
93+
public function init(int $symbols = StubsGenerator::DEFAULT, array $config = [])
9494
{
9595
$this->needsFunctions = ($symbols & StubsGenerator::FUNCTIONS) !== 0;
9696
$this->needsClasses = ($symbols & StubsGenerator::CLASSES) !== 0;

src/StubsGenerator.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,15 +106,21 @@ public function __construct(int $symbols = self::DEFAULT, array $config = [])
106106
* pretty-printed stubs.
107107
*
108108
* @param Finder $finder The set of files to generate (merged) stubs for.
109+
* @param NodeVisitor $visitor The optional node visitor to override the default.
109110
*
110111
* @return Result
111112
*/
112-
public function generate(Finder $finder): Result
113+
public function generate(Finder $finder, NodeVisitor $visitor = null): Result
113114
{
114115
$parser = (new ParserFactory())->create(ParserFactory::PREFER_PHP7);
115116

117+
if (!($visitor instanceof NodeVisitor)) {
118+
$visitor = new NodeVisitor;
119+
}
120+
121+
$visitor->init($this->symbols, $this->config);
122+
116123
$traverser = new NodeTraverser();
117-
$visitor = new NodeVisitor($this->symbols, $this->config);
118124
$traverser->addVisitor(new NameResolver());
119125
$traverser->addVisitor($visitor);
120126

test/NodeVisitorTest.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ private function parse(string $php, int $symbols, array $config): NodeVisitor
1616

1717
$traverser = new NodeTraverser();
1818
$traverser->addVisitor(new NameResolver());
19-
$visitor = new NodeVisitor($symbols, $config);
19+
$visitor = new NodeVisitor();
20+
$visitor->init($symbols, $config);
2021
$traverser->addVisitor($visitor);
2122

2223
$stmts = $parser->parse($php);

0 commit comments

Comments
 (0)