Skip to content

Commit

Permalink
Meta: Start writing stub generation script
Browse files Browse the repository at this point in the history
  • Loading branch information
ryangjchandler committed Jan 17, 2025
1 parent 97babe2 commit d4577f6
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 3 deletions.
6 changes: 4 additions & 2 deletions Justfile
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
test:
cargo test --workspace --lib --bins --tests

generate-ast:
ast:
php ./meta/generate-ast.php
php ./meta/generate-visitor.php
cargo fmt --package pxp-ast

generate-stubs:
stubs:
php ./meta/generate-stubs.php

meta: ast stubs
113 changes: 112 additions & 1 deletion meta/generate-stubs.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,116 @@
<?php

namespace Pxp;

use FilesystemIterator;
use PhpParser\Node;
use PhpParser\Node\ComplexType;
use PhpParser\Node\Identifier;
use PhpParser\Node\Name;
use PhpParser\Node\Param;
use PhpParser\Node\Stmt\Function_;
use PhpParser\NodeTraverser;
use PhpParser\NodeVisitor\NameResolver;
use PhpParser\NodeVisitorAbstract;
use PhpParser\Parser;
use PhpParser\ParserFactory;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use SplFileInfo;

require_once __DIR__ . '/../vendor/autoload.php';

$stubsDir = __DIR__ . '/../stubs';
final class Processor
{
private RecursiveIteratorIterator $stubs;

private array $entities = [];

private Parser $parser;

public function __construct()
{
$this->stubs = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(__DIR__ . '/../stubs', FilesystemIterator::SKIP_DOTS));
$this->parser = (new ParserFactory)->createForNewestSupportedVersion();
}

public function process(): void
{
foreach ($this->stubs as $stub) {
$this->stub($stub);
}

dd($this->entities);
}

private function stub(SplFileInfo $file): void
{
if ($file->getFilename() === 'LICENSE') {
return;
}

$contents = file_get_contents($file->getRealPath());

$traverser = new NodeTraverser(new NameResolver(options: [
'preserveOriginalNames' => true,
]));

$ast = $traverser->traverse($this->parser->parse($contents));

$traverser = new NodeTraverser(new EntityLocatingVisitor($this->entities));

$traverser->traverse($ast);
}
}

final class EntityLocatingVisitor extends NodeVisitorAbstract
{
public function __construct(private array &$entities) {}

public function enterNode(Node $node)
{
if ($node instanceof Function_) {
$this->processFunction($node);
}
}

private function processFunction(Function_ $node): void
{
$this->entities[] = [
'type' => 'FunctionEntity',
'name' => [
'resolved' => $node->namespacedName->toString(),
'original' => $node->name->toString(),
],
'parameters' => $this->processParameters($node->getParams()),
'return_type' => $this->processType($node->getReturnType()),
'returns_reference' => $node->returnsByRef(),
'location' => [
'file' => 0,
'span' => [$node->getStartFilePos(), $node->getEndFilePos()],
],
];
}

/**
* @param array<Param> $parameters
*/
private function processParameters(array $parameters): array
{
return array_map(function (Param $param) {

}, $parameters);
}

private function processType(Identifier|Name|ComplexType|null $type): ?array
{
if ($type === null) {
return null;
}

return [];
}
}

$processor = new Processor();
$processor->process();

0 comments on commit d4577f6

Please sign in to comment.