30b936be3da07bbcd7155a61e18a81ef83d24b8e
[mdref/mdref] / mdref / Generator / Scrap.php
1 <?php
2
3 namespace mdref\Generator;
4
5 use mdref\Generator;
6 use mdref\Generator\{Arg, Param};
7 use phpDocumentor\Reflection\{DocBlock, DocBlockFactory, DocBlock\Tags};
8
9 use Reflector;
10
11 class Scrap {
12 public function __construct(
13 protected Generator $gen,
14 protected Reflector $ref,
15 protected ?DocBlock $doc = null,
16 bool $overrideDocFromRef = false,
17 ) {
18 if ($overrideDocFromRef || !$this->doc) {
19 $this->createDocBlock();
20 }
21 if (!$this->doc) {
22 fprintf(STDERR, ... match (get_class($ref)) {
23 \ReflectionClass::class => ["Missing docs for class %s\n", $ref->name],
24 \ReflectionMethod::class => ["Missing docs for method %s::%s()\n", $ref->class, $ref->name],
25 \ReflectionProperty::class => ["Missing docs for property %s %s::\$%s\n", $ref->getType(), $ref->class, $ref->name],
26 \ReflectionClassConstant::class => ["Missing docs for constant %s::%s\n", $ref->class, $ref->name],
27 \ReflectionFunction::class => ["Missing docs for function %s()\n", $ref->name],
28 \ReflectionParameter::class => ($ref->getDeclaringClass()
29 ? ["Missing docs for method arg %s::%s(%s $%s)\n", $ref->getDeclaringClass()->name]
30 : ["Missing docs for function arg %s(%s $%s)\n"])
31 + [3=>$ref->getDeclaringFunction()->name, $ref->getType(), $ref->name],
32 default => ["Missing docs for ??? %s\n", $ref->name],
33 });
34 }
35 }
36
37 protected function createDocBlock() {
38 if (method_exists($this->ref, "getDocComment")) {
39 $docs = $this->ref->getDocComment();
40 } elseif (($this->ref instanceof \ReflectionParameter) && $this->ref->getDeclaringClass()?->hasProperty($this->ref->name)) {
41 // ctor promoted properties
42 $docs = $this->ref->getDeclaringClass()->getProperty($this->ref->name)->getDocComment();
43 }
44 if (isset($docs) && $docs !== false && strlen($docs)) {
45 $this->doc = DocBlockFactory::createInstance()->create((string) $docs);
46 }
47 }
48
49 protected function toString(string $file, int $offset, array $imports = []) : string {
50 $tpl = (string) new Template($file, $offset);
51 $patch = function(string $scrap_class, Reflector $ref) : void {
52 echo new $scrap_class($this->gen, $ref, $this->doc, true);
53 };
54 return (static function(Generator $gen, Reflector $ref, ?DocBlock $doc) use($patch) {
55 $imports = func_get_arg(3); extract($imports); unset($imports);
56 ob_start(null, 0x4000);
57 include func_get_arg(4);
58 return ob_get_clean();
59 })($this->gen, $this->ref, $this->doc, $imports, $tpl);
60 }
61
62 protected function getParamTag(string $var_name) : ?Tags\Param {
63 if ($this->doc) foreach ($this->doc->getTagsByName("param") as $param) {
64 if ($param->getVariableName() === $var_name) {
65 return $param;
66 }
67 }
68 return null;
69 }
70
71 protected function getVarTag(string $var_name) : ?Tags\Var_ {
72 if ($this->doc) foreach ($this->doc->getTagsByName("var") as $prop) {
73 if ($prop->getVariableName() === $var_name) {
74 return $prop;
75 }
76 }
77 return null;
78 }
79 }