From 5162a67bc4772df23a63a68ee4e3fec2ff45986e Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Sun, 26 Jul 2020 13:41:42 +0200 Subject: [PATCH] Generate docbook methodsynopses from stubs --- build/gen_stub.php | 110 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 107 insertions(+), 3 deletions(-) diff --git a/build/gen_stub.php b/build/gen_stub.php index 43470497d27a..c965c58ec810 100755 --- a/build/gen_stub.php +++ b/build/gen_stub.php @@ -67,6 +67,106 @@ function extractStubHash(string $arginfoFile): ?string { return $matches[1]; } +function generateMethodsynopses(string $stubFile): void { + try { + if (!file_exists($stubFile)) { + throw new Exception("File $stubFile does not exist"); + } + + $docFile = str_replace('.stub.php', '.stub.xml', $stubFile); + $stubCode = file_get_contents($stubFile); + + initPhpParser(); + $fileInfo = parseStubFile($stubCode); + $doc = new DOMDocument(); + $doc->appendChild($doc->createElement('methodsynopses')); + foreach ($fileInfo->getAllFuncInfos() as $funcInfo) { + $comment = $doc->createComment(" {$funcInfo->name} "); + $doc->documentElement->appendChild($comment); + $doc->documentElement->appendChild(generateMethodsynopsis($doc, $funcInfo)); + } + file_put_contents($docFile, getFormattedXML($doc)); + } catch (Exception $e) { + echo "In $stubFile:\n{$e->getMessage()}\n"; + exit(1); + } +} + +function generateMethodsynopsis(DOMDocument $doc, FuncInfo $funcInfo): DOMElement { + $methodsynopsis = $doc->createElement('methodsynopsis'); + $typeString = getTypeAsString($funcInfo->return->type); + $type = $doc->createElement('type', $typeString); + $methodsynopsis->appendChild($type); + $methodname = $doc->createElement('methodname', $funcInfo->name->name); + $methodsynopsis->appendChild($methodname); + if (empty($funcInfo->args)) { + $void = $doc->createElement('void'); + $methodsynopsis->appendChild($void); + } else foreach ($funcInfo->args as $arg) { + $methodparam = $doc->createElement('methodparam'); + if ($arg->defaultValue !== null) { + $choice = $doc->createAttribute('choice'); + $choice->value = "opt"; + $methodparam->appendChild($choice); + } + $methodsynopsis->appendChild($methodparam); + $type = $doc->createElement('type', getTypeAsString($arg->type)); + $methodparam->appendChild($type); + $parameter = $doc->createElement('parameter', $arg->name); + if ($arg->sendBy !== ArgInfo::SEND_BY_VAL) { + $role = $doc->createAttribute('role'); + $role->value = "reference"; + $parameter->appendChild($role); + } + $methodparam->appendChild($parameter); + $defaultValue = getDefaultValue($arg); + if ($defaultValue !== null) { + $initializer = $doc->createElement('initializer'); + if (preg_match('/^[a-zA-Z_][a-zA-Z_0-9]*$/', $defaultValue)) { + $constant = $doc->createElement('constant', $defaultValue); + $initializer->appendChild($constant); + } else { + $initializer->nodeValue = $defaultValue; + } + $methodparam->appendChild($initializer); + } + } + return $methodsynopsis; +} + +function getTypeAsString(?Type $type): string { + if ($type === null || $type->types === null) { + return 'mixed'; + } + return implode('|', array_map(function ($type) {return $type->name;}, $type->types)); +} + +function getDefaultValue(ArgInfo $arg): ?string { + if ($arg->defaultValue === null) { + return null; + } + switch ($arg->defaultValue) { + case 'UNKNOWN': + return null; + case 'false': + case 'true': + case 'null': + return "&{$arg->defaultValue};"; + } + return $arg->defaultValue; +} + +function getFormattedXML(DOMDocument $doc): string { + $xml = $doc->saveXML(); + $xml = str_replace('