Skip to content

Commit d44992f

Browse files
committed
Add support for replacing class synopses based on stubs
1 parent 86bc48c commit d44992f

File tree

1 file changed

+152
-10
lines changed

1 file changed

+152
-10
lines changed

build/gen_stub.php

Lines changed: 152 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1494,7 +1494,7 @@ public function getClassSynopsisElement(DOMDocument $doc, array $classMap): ?DOM
14941494
$parentClassName = self::getClassSynopsisFilename($parent);
14951495
$includeElement = $this->createIncludeElement(
14961496
$doc,
1497-
"xmlns(db=http://docbook.org/ns/docbook) xpointer(id('class.$parentClassName')/db:partintro/db:section/db:classsynopsis/db:fieldsynopsis[preceding-sibling::db:classsynopsisinfo[1][@role='comment' and text()='&Properties;']]))"
1497+
"xmlns(db=http://docbook.org/ns/docbook) xpointer(id('class.$parentClassName')/db:partintro/db:section/db:classsynopsis/db:fieldsynopsis[preceding-sibling::db:classsynopsisinfo[1][@role='comment' and text()='Properties']]))"
14981498
);
14991499
$classSynopsis->appendChild($includeElement);
15001500
}
@@ -1512,7 +1512,7 @@ public function getClassSynopsisElement(DOMDocument $doc, array $classMap): ?DOM
15121512
$classSynopsis->appendChild(new DOMText("\n "));
15131513
$includeElement = $this->createIncludeElement(
15141514
$doc,
1515-
"xmlns(db=http://docbook.org/ns/docbook) xpointer(id('class.$className')/db:refentry/db:refsect1[@role='description']/descendant::db:constructorsynopsis[not(@role='procedural')]"
1515+
"xmlns(db=http://docbook.org/ns/docbook) xpointer(id('class.$className')/db:refentry/db:refsect1[@role='description']/descendant::db:constructorsynopsis[not(@role='procedural')])"
15161516
);
15171517
$classSynopsis->appendChild($includeElement);
15181518
}
@@ -1530,7 +1530,7 @@ public function getClassSynopsisElement(DOMDocument $doc, array $classMap): ?DOM
15301530
$classSynopsis->appendChild(new DOMText("\n "));
15311531
$includeElement = $this->createIncludeElement(
15321532
$doc,
1533-
"xmlns(db=http://docbook.org/ns/docbook) xpointer(id('class.$className')/db:refentry/db:refsect1[@role='description']/descendant::db:destructorsynopsis[not(@role='procedural')]"
1533+
"xmlns(db=http://docbook.org/ns/docbook) xpointer(id('class.$className')/db:refentry/db:refsect1[@role='description']/descendant::db:destructorsynopsis[not(@role='procedural')])"
15341534
);
15351535
$classSynopsis->appendChild($includeElement);
15361536
}
@@ -2440,7 +2440,150 @@ function generateClassSynopses(array $classMap): array {
24402440
*/
24412441
function replaceClassSynopses(string $targetDirectory, array $classMap): array
24422442
{
2443-
throw new Exception("Not yet implemented!");
2443+
$classSynopses = [];
2444+
2445+
$it = new RecursiveIteratorIterator(
2446+
new RecursiveDirectoryIterator($targetDirectory),
2447+
RecursiveIteratorIterator::LEAVES_ONLY
2448+
);
2449+
2450+
foreach ($it as $file) {
2451+
$pathName = $file->getPathName();
2452+
if (!preg_match('/\.xml$/i', $pathName)) {
2453+
continue;
2454+
}
2455+
2456+
$xml = file_get_contents($pathName);
2457+
if ($xml === false) {
2458+
continue;
2459+
}
2460+
2461+
if (stripos($xml, "<classsynopsis") === false) {
2462+
continue;
2463+
}
2464+
2465+
$replacedXml = preg_replace(
2466+
[
2467+
"/&([A-Za-z0-9._{}%-]+?;)/",
2468+
"/<(\/)*xi:([A-Za-z]+?)/"
2469+
],
2470+
[
2471+
"REPLACED-ENTITY-$1",
2472+
"<$1XI$2",
2473+
],
2474+
$xml
2475+
);
2476+
2477+
$doc = new DOMDocument();
2478+
$doc->formatOutput = false;
2479+
$doc->preserveWhiteSpace = true;
2480+
$doc->validateOnParse = true;
2481+
$success = $doc->loadXML($replacedXml);
2482+
if (!$success) {
2483+
echo "Failed opening $pathName\n";
2484+
continue;
2485+
}
2486+
2487+
$docComparator = new DOMDocument();
2488+
$docComparator->preserveWhiteSpace = false;
2489+
$docComparator->formatOutput = true;
2490+
2491+
$classSynopsisElements = [];
2492+
foreach ($doc->getElementsByTagName("classsynopsis") as $element) {
2493+
$classSynopsisElements[] = $element;
2494+
}
2495+
2496+
foreach ($classSynopsisElements as $classSynopsis) {
2497+
if (!$classSynopsis instanceof DOMElement) {
2498+
continue;
2499+
}
2500+
2501+
$firstChild = $classSynopsis->firstElementChild;
2502+
if ($firstChild === null) {
2503+
continue;
2504+
}
2505+
$firstChild = $firstChild->firstElementChild;
2506+
if ($firstChild === null) {
2507+
continue;
2508+
}
2509+
$className = $firstChild->textContent;
2510+
if (!isset($classMap[$className])) {
2511+
continue;
2512+
}
2513+
$classInfo = $classMap[$className];
2514+
2515+
$newClassSynopsis = $classInfo->getClassSynopsisElement($doc, $classMap);
2516+
if ($newClassSynopsis === null) {
2517+
continue;
2518+
}
2519+
2520+
// Check if there is any change - short circuit if there is not any.
2521+
2522+
$xml1 = $doc->saveXML($classSynopsis);
2523+
$xml1 = preg_replace(
2524+
[
2525+
"/&([A-Za-z0-9._{}%-]+?;)/",
2526+
"/<xi:([A-Za-z]+?)/",
2527+
'#</xi:([A-Za-z]+?)#',
2528+
],
2529+
[
2530+
"REPLACED-ENTITY-$1",
2531+
"<XI$1",
2532+
"<XI$1",
2533+
],
2534+
$xml1
2535+
);
2536+
$docComparator->loadXML($xml1);
2537+
$xml1 = $docComparator->saveXML();
2538+
2539+
$classSynopsis->parentNode->replaceChild($newClassSynopsis, $classSynopsis);
2540+
2541+
$xml2 = $doc->saveXML($newClassSynopsis);
2542+
$xml2 = preg_replace(
2543+
[
2544+
"/&([A-Za-z0-9._{}%-]+?;)/",
2545+
"/<xi:([A-Za-z]+?)/",
2546+
'#</xi:([A-Za-z]+?)#',
2547+
],
2548+
[
2549+
"REPLACED-ENTITY-$1",
2550+
"<XI$1",
2551+
"</XI$1",
2552+
],
2553+
$xml2
2554+
);
2555+
2556+
$docComparator->loadXML($xml2);
2557+
$xml2 = $docComparator->saveXML();
2558+
2559+
2560+
if ($xml1 === $xml2) {
2561+
continue;
2562+
}
2563+
2564+
// Return the updated XML
2565+
2566+
$replacedXml = $doc->saveXML();
2567+
2568+
$replacedXml = preg_replace(
2569+
[
2570+
"/REPLACED-ENTITY-([A-Za-z0-9._{}%-]+?;)/",
2571+
"/<phpdoc:classref\s+xmlns:phpdoc=\"([a-z0-9.:\/]+)\"\s+xmlns=\"([a-z0-9.:\/]+)\"\s+xmlns:xi=\"([a-z0-9.:\/]+)\"\s+xml:id=\"([a-z0-9._-]+)\"\s*>/i",
2572+
"/<phpdoc:classref\s+xmlns:phpdoc=\"([a-z0-9.:\/]+)\"\s+xmlns=\"([a-z0-9.:\/]+)\"\s+xmlns:xlink=\"([a-z0-9.:\/]+)\"\s+xmlns:xi=\"([a-z0-9.:\/]+)\"\s+xml:id=\"([a-z0-9._-]+)\"\s*>/i",
2573+
],
2574+
[
2575+
"&$1",
2576+
"<phpdoc:classref xml:id=\"$4\" xmlns:phpdoc=\"$1\" xmlns=\"$2\" xmlns:xi=\"$4\">",
2577+
"<phpdoc:classref xml:id=\"$5\" xmlns:phpdoc=\"$1\" xmlns=\"$2\" xmlns:xlink=\"$3\" xmlns:xi=\"$4\">",
2578+
],
2579+
$replacedXml
2580+
);
2581+
2582+
$classSynopses[$pathName] = $replacedXml;
2583+
}
2584+
}
2585+
2586+
return $classSynopses;
24442587
}
24452588

24462589
/**
@@ -2715,13 +2858,12 @@ function initPhpParser() {
27152858
$context->forceRegeneration = isset($options["f"]) || isset($options["force-regeneration"]);
27162859
$context->forceParse = $context->forceRegeneration || $printParameterStats || $verify || $generateClassSynopses || $replaceClassSynopses || $generateMethodSynopses || $replaceMethodSynopses;
27172860

2718-
$targetClassSynopses = $argv[$optind + 1] ?? null;
2719-
if ($replaceClassSynopses && $targetClassSynopses === null) {
2861+
$targetSynopses = $argv[$argc - 1] ?? null;
2862+
if ($replaceClassSynopses && $targetSynopses === null) {
27202863
die("A target class synopsis directory must be provided for.\n");
27212864
}
27222865

2723-
$targetMethodSynopses = $argv[$optind + 1 + ($targetClassSynopses !== null)] ?? null;
2724-
if ($replaceMethodSynopses && $targetMethodSynopses === null) {
2866+
if ($replaceMethodSynopses && $targetSynopses === null) {
27252867
die("A target method synopsis directory must be provided.\n");
27262868
}
27272869

@@ -2884,7 +3026,7 @@ function(?ArgInfo $aliasArg, ?ArgInfo $aliasedArg) use ($aliasFunc, $aliasedFunc
28843026
}
28853027

28863028
if ($replaceClassSynopses) {
2887-
$classSynopses = replaceClassSynopses($targetClassSynopses, $classMap);
3029+
$classSynopses = replaceClassSynopses($targetSynopses, $classMap);
28883030

28893031
foreach ($classSynopses as $filename => $content) {
28903032
if (file_put_contents($filename, $content)) {
@@ -2912,7 +3054,7 @@ function(?ArgInfo $aliasArg, ?ArgInfo $aliasedArg) use ($aliasFunc, $aliasedFunc
29123054
}
29133055

29143056
if ($replaceMethodSynopses) {
2915-
$methodSynopses = replaceMethodSynopses($targetMethodSynopses, $funcMap, $aliasMap);
3057+
$methodSynopses = replaceMethodSynopses($targetSynopses, $funcMap, $aliasMap);
29163058

29173059
foreach ($methodSynopses as $filename => $content) {
29183060
if (file_put_contents($filename, $content)) {

0 commit comments

Comments
 (0)