Skip to content

Commit ed09cce

Browse files
committed
gen_stub: Generate useful methodsynopsises
So that they can be used as a starting point for new functions/methods.
1 parent 6a4031b commit ed09cce

File tree

1 file changed

+302
-9
lines changed

1 file changed

+302
-9
lines changed

build/gen_stub.php

Lines changed: 302 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1060,7 +1060,7 @@ public function getArgInfoName(): string {
10601060
}
10611061

10621062
public function getMethodSynopsisFilename(): string {
1063-
return implode('_', $this->name->getParts());
1063+
return 'functions/' . implode('/', str_replace('_', '-', $this->name->getParts()));
10641064
}
10651065

10661066
public function getNameForAttributes(): string {
@@ -1105,8 +1105,11 @@ public function getArgInfoName(): string {
11051105
return "arginfo_class_{$this->getDeclarationClassName()}_{$this->methodName}";
11061106
}
11071107

1108-
public function getMethodSynopsisFilename(): string {
1109-
return $this->getDeclarationClassName() . "_{$this->methodName}";
1108+
public function getMethodSynopsisFilename(): string
1109+
{
1110+
$parts = [...$this->className->getParts(), ltrim($this->methodName, '_')];
1111+
/* File paths are in lowercase */
1112+
return implode('/', array_map('strtolower', $parts));
11101113
}
11111114

11121115
public function getNameForAttributes(): string {
@@ -1486,17 +1489,300 @@ private function getFlagsAsArginfoString(): string
14861489
* @throws Exception
14871490
*/
14881491
public function getMethodSynopsisDocument(array $funcMap, array $aliasMap): ?string {
1489-
14901492
$doc = new DOMDocument();
14911493
$doc->formatOutput = true;
1494+
1495+
$refentry = $doc->createElement('refentry');
1496+
$doc->appendChild($refentry);
1497+
1498+
if ($this->isMethod()) {
1499+
assert($this->name instanceof MethodName);
1500+
$id = $doc->createAttribute("xml:id");
1501+
$id->value = addslashes(strtolower($this->name->className->__toString())) . '.' . strtolower($this->name->methodName);
1502+
$refentry->appendChild($id);
1503+
} else {
1504+
// TODO Functions
1505+
}
1506+
$refentry->setAttribute("xmlns", "http://docbook.org/ns/docbook");
1507+
$refentry->appendChild(new DOMText("\n "));
1508+
1509+
/* Creation of <refnamediv> */
1510+
$refnamediv = $doc->createElement('refnamediv');
1511+
$refnamediv->appendChild(new DOMText("\n "));
1512+
if ($this->isMethod()) {
1513+
assert($this->name instanceof MethodName);
1514+
$refname = $doc->createElement('refname', $this->name->className->__toString() . '::' . $this->name->methodName);
1515+
$refnamediv->appendChild($refname);
1516+
} else {
1517+
// TODO Functions
1518+
}
1519+
$refnamediv->appendChild(new DOMText("\n "));
1520+
$refpurpose = $doc->createElement('refpurpose', 'Description');
1521+
$refnamediv->appendChild($refpurpose);
1522+
1523+
$refnamediv->appendChild(new DOMText("\n "));
1524+
$refentry->appendChild($refnamediv);
1525+
$refentry->appendChild(new DOMText("\n\n "));
1526+
1527+
/* Creation of <refsect1 role="description"> */
1528+
$descriptionRefSec = $doc->createElement('refsect1');
1529+
$descriptionRefSec->setAttribute('role', 'description');
1530+
$descriptionRefSec->appendChild(new DOMText("\n "));
1531+
$refTitleDescription = $doc->createEntityReference('reftitle.description');
1532+
$descriptionRefSec->appendChild($refTitleDescription);
1533+
$descriptionRefSec->appendChild(new DOMText("\n "));
1534+
14921535
$methodSynopsis = $this->getMethodSynopsisElement($funcMap, $aliasMap, $doc);
14931536
if (!$methodSynopsis) {
14941537
return null;
14951538
}
1539+
$descriptionRefSec->appendChild($methodSynopsis);
1540+
$descriptionRefSec->appendChild(new DOMText("\n "));
1541+
$undocumentedEntity = $doc->createEntityReference('warn.undocumented.func');
1542+
$descriptionRefSec->appendChild($undocumentedEntity);
1543+
$descriptionRefSec->appendChild(new DOMText("\n "));
1544+
$returnDescriptionPara = $doc->createElement('para');
1545+
$returnDescriptionPara->appendChild(new DOMText("\n Description\n "));
1546+
$descriptionRefSec->appendChild($returnDescriptionPara);
1547+
1548+
$descriptionRefSec->appendChild(new DOMText("\n "));
1549+
$refentry->appendChild($descriptionRefSec);
1550+
$refentry->appendChild(new DOMText("\n\n "));
1551+
1552+
/* Creation of <refsect1 role="parameters"> */
1553+
$parametersRefSec = $this->getParameterSection($doc);
1554+
$refentry->appendChild($parametersRefSec);
1555+
$refentry->appendChild(new DOMText("\n\n "));
1556+
1557+
/* Creation of <refsect1 role="returnvalues"> */
1558+
$returnRefSec = $this->getReturnValueSection($doc);
1559+
$refentry->appendChild($returnRefSec);
1560+
$refentry->appendChild(new DOMText("\n\n "));
1561+
1562+
/* Creation of <refsect1 role="errors"> */
1563+
$errorsRefSec = $doc->createElement('refsect1');
1564+
$errorsRefSec->setAttribute('role', 'errors');
1565+
$errorsRefSec->appendChild(new DOMText("\n "));
1566+
$refTitleErrors = $doc->createEntityReference('reftitle.errors');
1567+
$errorsRefSec->appendChild($refTitleErrors);
1568+
$errorsRefSec->appendChild(new DOMText("\n "));
1569+
$errorsDescriptionPara = $doc->createElement('para');
1570+
$errorsDescriptionPara->appendChild(new DOMText("\n When does this function issue E_* level errors, and/or throw exceptions.\n "));
1571+
$errorsRefSec->appendChild($errorsDescriptionPara);
1572+
$errorsRefSec->appendChild(new DOMText("\n "));
1573+
1574+
$refentry->appendChild($errorsRefSec);
1575+
$refentry->appendChild(new DOMText("\n\n "));
1576+
1577+
/* Creation of <refsect1 role="changelog"> */
1578+
$changelogRefSec = $this->getChangelogSection($doc);
1579+
$refentry->appendChild($changelogRefSec);
1580+
1581+
// TODO Examples, Notes, and See Also sections
1582+
1583+
$refentry->appendChild(new DOMText("\n\n"));
1584+
1585+
$doc->appendChild(new DOMComment(
1586+
<<<ENDCOMMENT
1587+
Keep this comment at the end of the file
1588+
Local variables:
1589+
mode: sgml
1590+
sgml-omittag:t
1591+
sgml-shorttag:t
1592+
sgml-minimize-attributes:nil
1593+
sgml-always-quote-attributes:t
1594+
sgml-indent-step:1
1595+
sgml-indent-data:t
1596+
indent-tabs-mode:nil
1597+
sgml-parent-document:nil
1598+
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
1599+
sgml-exposed-tags:nil
1600+
sgml-local-catalogs:nil
1601+
sgml-local-ecat-files:nil
1602+
End:
1603+
vim600: syn=xml fen fdm=syntax fdl=2 si
1604+
vim: et tw=78 syn=sgml
1605+
vi: ts=1 sw=1
1606+
1607+
ENDCOMMENT
1608+
));
1609+
return $doc->saveXML();
1610+
}
1611+
1612+
private function getParameterSection(DOMDocument $doc): DOMElement {
1613+
$parametersRefSec = $doc->createElement('refsect1');
1614+
$parametersRefSec->setAttribute('role', 'parameters');
1615+
$parametersRefSec->appendChild(new DOMText("\n "));
1616+
$refTitle = $doc->createEntityReference('reftitle.parameters');
1617+
$parametersRefSec->appendChild($refTitle);
1618+
$parametersRefSec->appendChild(new DOMText("\n "));
1619+
if (empty($this->args)) {
1620+
$noParamEntity = $doc->createEntityReference('no.function.parameters');
1621+
$parametersRefSec->appendChild($noParamEntity);
1622+
return $parametersRefSec;
1623+
} else {
1624+
$parametersPara = $doc->createElement('para');
1625+
$parametersRefSec->appendChild($parametersPara);
1626+
1627+
$parametersPara->appendChild(new DOMText("\n "));
1628+
$parametersList = $doc->createElement('variablelist');
1629+
$parametersPara->appendChild($parametersList);
1630+
1631+
/*
1632+
<varlistentry>
1633+
<term><parameter>name</parameter></term>
1634+
<listitem>
1635+
<para>
1636+
Description.
1637+
</para>
1638+
</listitem>
1639+
</varlistentry>
1640+
*/
1641+
foreach ($this->args as $arg) {
1642+
$parameter = $doc->createElement('parameter', $arg->name);
1643+
$parameterTerm = $doc->createElement('term');
1644+
$parameterTerm->appendChild($parameter);
1645+
1646+
$parameterEntry = $doc->createElement('varlistentry');
1647+
$parameterEntry->appendChild(new DOMText("\n "));
1648+
$parameterEntry->appendChild($parameterTerm);
1649+
$parameterEntry->appendChild(new DOMText("\n "));
1650+
1651+
$listItemPara = $doc->createElement('para');
1652+
$listItemPara->appendChild(new DOMText("\n "));
1653+
$listItemPara->appendChild(new DOMText("Description."));
1654+
$listItemPara->appendChild(new DOMText("\n "));
1655+
1656+
$parameterEntryListItem = $doc->createElement('listitem');
1657+
$parameterEntryListItem->appendChild(new DOMText("\n "));
1658+
$parameterEntryListItem->appendChild($listItemPara);
1659+
$parameterEntryListItem->appendChild(new DOMText("\n "));
1660+
1661+
$parameterEntry->appendChild($parameterEntryListItem);
1662+
$parameterEntry->appendChild(new DOMText("\n "));
1663+
1664+
$parametersList->appendChild($parameterEntry);
1665+
$parametersList->appendChild(new DOMText("\n "));
1666+
}
1667+
}
1668+
$parametersPara->appendChild(new DOMText("\n "));
1669+
$parametersRefSec->appendChild(new DOMText("\n "));
1670+
return $parametersRefSec;
1671+
}
1672+
1673+
private function getReturnValueSection(DOMDocument $doc): DOMElement {
1674+
$returnRefSec = $doc->createElement('refsect1');
1675+
$returnRefSec->setAttribute('role', 'returnvalues');
1676+
$returnRefSec->appendChild(new DOMText("\n "));
1677+
$refTitle = $doc->createEntityReference('reftitle.returnvalues');
1678+
$returnRefSec->appendChild($refTitle);
1679+
$returnRefSec->appendChild(new DOMText("\n "));
1680+
$returnDescriptionPara = $doc->createElement('para');
1681+
$returnDescriptionPara->appendChild(new DOMText("\n "));
1682+
1683+
$returnType = $this->return->type;
1684+
if ($returnType === null) {
1685+
$returnDescriptionPara->appendChild(new DOMText("Description"));
1686+
} else if (count($returnType->types) === 1) {
1687+
$type = $returnType->types[0];
1688+
$name = $type->name;
1689+
$descriptionNode = match ($name) {
1690+
'void' => $doc->createEntityReference('return.void'),
1691+
'true' => $doc->createEntityReference('return.true.always'),
1692+
'bool' => $doc->createEntityReference('return.success'),
1693+
default => new DOMText("Description"),
1694+
};
1695+
$returnDescriptionPara->appendChild($descriptionNode);
1696+
} else {
1697+
$returnDescriptionPara->appendChild(new DOMText("Description"));
1698+
}
1699+
$returnDescriptionPara->appendChild(new DOMText("\n "));
1700+
$returnRefSec->appendChild($returnDescriptionPara);
1701+
$returnRefSec->appendChild(new DOMText("\n "));
1702+
return $returnRefSec;
1703+
}
14961704

1497-
$doc->appendChild($methodSynopsis);
1705+
/**
1706+
* @param array<DOMNode> $headers [count($headers) === $columns]
1707+
* @param array<array<DOMNode>> $rows [count($rows[$i]) === $columns]
1708+
*/
1709+
private function generateDocbookInformalTable(
1710+
DOMDocument $doc,
1711+
int $indent,
1712+
int $columns,
1713+
array $headers,
1714+
array $rows
1715+
): DOMElement {
1716+
$strIndent = str_repeat(' ', $indent);
1717+
1718+
$headerRow = $doc->createElement('row');
1719+
foreach ($headers as $header) {
1720+
$headerEntry = $doc->createElement('entry');
1721+
$headerEntry->appendChild($header);
1722+
1723+
$headerRow->appendChild(new DOMText("\n$strIndent "));
1724+
$headerRow->appendChild($headerEntry);
1725+
}
1726+
$headerRow->appendChild(new DOMText("\n$strIndent "));
1727+
1728+
$thead = $doc->createElement('thead');
1729+
$thead->appendChild(new DOMText("\n$strIndent "));
1730+
$thead->appendChild($headerRow);
1731+
$thead->appendChild(new DOMText("\n$strIndent "));
1732+
1733+
$tbody = $doc->createElement('tbody');
1734+
foreach ($rows as $row) {
1735+
$bodyRow = $doc->createElement('row');
1736+
foreach ($row as $cell) {
1737+
$entry = $doc->createElement('entry');
1738+
$entry->appendChild($cell);
1739+
1740+
$bodyRow->appendChild(new DOMText("\n$strIndent "));
1741+
$bodyRow->appendChild($entry);
1742+
}
1743+
$bodyRow->appendChild(new DOMText("\n$strIndent "));
1744+
1745+
$tbody->appendChild(new DOMText("\n$strIndent "));
1746+
$tbody->appendChild($bodyRow);
1747+
$tbody->appendChild(new DOMText("\n$strIndent "));
1748+
}
1749+
1750+
$tgroup = $doc->createElement('tgroup');
1751+
$tgroup->setAttribute('cols', (string) $columns);
1752+
$tgroup->appendChild(new DOMText("\n$strIndent "));
1753+
$tgroup->appendChild($thead);
1754+
$tgroup->appendChild(new DOMText("\n$strIndent "));
1755+
$tgroup->appendChild($tbody);
1756+
$tgroup->appendChild(new DOMText("\n$strIndent "));
1757+
1758+
$table = $doc->createElement('informaltable');
1759+
$table->appendChild(new DOMText("\n$strIndent "));
1760+
$table->appendChild($tgroup);
1761+
$table->appendChild(new DOMText("\n$strIndent"));
1762+
1763+
return $table;
1764+
}
1765+
1766+
private function getChangelogSection(DOMDocument $doc): DOMElement {
1767+
$refSec = $doc->createElement('refsect1');
1768+
$refSec->setAttribute('role', 'changelog');
1769+
$refSec->appendChild(new DOMText("\n "));
1770+
$refTitle = $doc->createEntityReference('reftitle.changelog');
1771+
$refSec->appendChild($refTitle);
1772+
$refSec->appendChild(new DOMText("\n "));
1773+
$headers = [
1774+
$doc->createEntityReference('Version'),
1775+
$doc->createEntityReference('Description'),
1776+
];
1777+
$rows = [[
1778+
new DOMText('8.X.0'),
1779+
new DOMText("\n Description\n "),
1780+
]];
1781+
$table = $this->generateDocbookInformalTable($doc, indent: 2, columns: 2, headers: $headers, rows: $rows);
1782+
$refSec->appendChild($table);
14981783

1499-
return $doc->saveXML();
1784+
$refSec->appendChild(new DOMText("\n "));
1785+
return $refSec;
15001786
}
15011787

15021788
/**
@@ -5351,7 +5637,12 @@ function(?ArgInfo $aliasArg, ?ArgInfo $aliasedArg) use ($aliasFunc, $aliasedFunc
53515637
}
53525638

53535639
if ($generateMethodSynopses) {
5354-
$methodSynopsesDirectory = getcwd() . "/methodsynopses";
5640+
// Use the manual as target if we are targeting a specific extension
5641+
if (str_contains($manualTarget, 'reference')) {
5642+
$methodSynopsesDirectory = $manualTarget;
5643+
} else {
5644+
$methodSynopsesDirectory = getcwd() . "/methodsynopses";
5645+
}
53555646

53565647
$methodSynopses = generateMethodSynopses($funcMap, $aliasMap);
53575648
if (!empty($methodSynopses)) {
@@ -5360,8 +5651,10 @@ function(?ArgInfo $aliasArg, ?ArgInfo $aliasedArg) use ($aliasFunc, $aliasedFunc
53605651
}
53615652

53625653
foreach ($methodSynopses as $filename => $content) {
5363-
if (file_put_contents("$methodSynopsesDirectory/$filename", $content)) {
5364-
echo "Saved $filename\n";
5654+
if (!file_exists("$methodSynopsesDirectory/$filename")) {
5655+
if (file_put_contents("$methodSynopsesDirectory/$filename", $content)) {
5656+
echo "Saved $filename\n";
5657+
}
53655658
}
53665659
}
53675660
}

0 commit comments

Comments
 (0)