Skip to content

Commit

Permalink
Merge pull request #5 from johnbillion/custom-visitor
Browse files Browse the repository at this point in the history
  • Loading branch information
szepeviktor authored Dec 2, 2021
2 parents acf0f06 + cb070a7 commit 53c2cbb
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 5 deletions.
20 changes: 19 additions & 1 deletion src/GenerateStubsCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public function configure(): void
->addOption('out', null, InputOption::VALUE_REQUIRED, 'Path to a file to write pretty-printed stubs to. If unset, stubs will be written to stdout.')
->addOption('force', null, InputOption::VALUE_NONE, 'Whether to force an overwrite.')
->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.')
->addOption('visitor', null, InputOption::VALUE_REQUIRED, 'Path to a PHP file which returns a `StubsGenerator\NodeVisitor` instance to replace the default node visitor.')
->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.)', '')
->addOption('nullify-globals', null, InputOption::VALUE_NONE, 'Initialize all global variables with a value of `null`, instead of their assigned value.')
->addOption('stats', null, InputOption::VALUE_NONE, 'Whether to print stats instead of outputting stubs. Stats will always be printed if --out is provided.');
Expand Down Expand Up @@ -95,13 +96,30 @@ protected function interact(InputInterface $input, OutputInterface $output): voi
protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);
$visitor = null;
$visitorPath = $input->getOption('visitor');

if ($visitorPath) {
$visitorPath = $this->resolvePath($visitorPath);
if (!$this->filesystem->exists($visitorPath) || is_dir($visitorPath)) {
throw new InvalidArgumentException("Bad --visitor path: '$visitorPath' does not exist or is a directory.");
}
try {
$visitor = @include $visitorPath;
} catch (Exception $e) {
throw new RuntimeException("Could not resolve a `StubsGenerator\NodeVisitor` from '$visitorPath'.", 0, $e);
}
if (!$visitor || !($visitor instanceof NodeVisitor)) {
throw new RuntimeException("Could not resolve a `StubsGenerator\NodeVisitor` from '$visitorPath'.");
}
}

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

$result = $generator->generate($finder);
$result = $generator->generate($finder, $visitor);

$printer = new Standard();

Expand Down
2 changes: 1 addition & 1 deletion src/NodeVisitor.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ class NodeVisitor extends NodeVisitorAbstract
/**
* @param int $symbols Set of symbol types to include stubs for.
*/
public function __construct(int $symbols = StubsGenerator::DEFAULT, array $config = [])
public function init(int $symbols = StubsGenerator::DEFAULT, array $config = [])
{
$this->needsFunctions = ($symbols & StubsGenerator::FUNCTIONS) !== 0;
$this->needsClasses = ($symbols & StubsGenerator::CLASSES) !== 0;
Expand Down
10 changes: 8 additions & 2 deletions src/StubsGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -106,15 +106,21 @@ public function __construct(int $symbols = self::DEFAULT, array $config = [])
* pretty-printed stubs.
*
* @param Finder $finder The set of files to generate (merged) stubs for.
* @param NodeVisitor $visitor The optional node visitor to override the default.
*
* @return Result
*/
public function generate(Finder $finder): Result
public function generate(Finder $finder, NodeVisitor $visitor = null): Result
{
$parser = (new ParserFactory())->create(ParserFactory::PREFER_PHP7);

if (!($visitor instanceof NodeVisitor)) {
$visitor = new NodeVisitor;
}

$visitor->init($this->symbols, $this->config);

$traverser = new NodeTraverser();
$visitor = new NodeVisitor($this->symbols, $this->config);
$traverser->addVisitor(new NameResolver());
$traverser->addVisitor($visitor);

Expand Down
3 changes: 2 additions & 1 deletion test/NodeVisitorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ private function parse(string $php, int $symbols, array $config): NodeVisitor

$traverser = new NodeTraverser();
$traverser->addVisitor(new NameResolver());
$visitor = new NodeVisitor($symbols, $config);
$visitor = new NodeVisitor();
$visitor->init($symbols, $config);
$traverser->addVisitor($visitor);

$stmts = $parser->parse($php);
Expand Down

0 comments on commit 53c2cbb

Please sign in to comment.