Skip to content

Commit 8101337

Browse files
committed
Add file inclusion as a mechanism to find stub files and cross-reference constants
Signed-off-by: Bob Weinand <bobwei9@hotmail.com>
1 parent 3b2a0e7 commit 8101337

File tree

3 files changed

+55
-15
lines changed

3 files changed

+55
-15
lines changed

build/gen_stub.php

Lines changed: 52 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -46,28 +46,54 @@ function processDirectory(string $dir, Context $context): array {
4646
return $fileInfos;
4747
}
4848

49-
function processStubFile(string $stubFile, Context $context): ?FileInfo {
49+
function processStubFile(string $stubFile, Context $context, bool $includeOnly = false): ?FileInfo {
5050
try {
5151
if (!file_exists($stubFile)) {
5252
throw new Exception("File $stubFile does not exist");
5353
}
5454

55-
$stubFilenameWithoutExtension = str_replace(".stub.php", "", $stubFile);
56-
$arginfoFile = "{$stubFilenameWithoutExtension}_arginfo.h";
57-
$legacyFile = "{$stubFilenameWithoutExtension}_legacy_arginfo.h";
55+
if (!$includeOnly) {
56+
$stubFilenameWithoutExtension = str_replace(".stub.php", "", $stubFile);
57+
$arginfoFile = "{$stubFilenameWithoutExtension}_arginfo.h";
58+
$legacyFile = "{$stubFilenameWithoutExtension}_legacy_arginfo.h";
5859

59-
$stubCode = file_get_contents($stubFile);
60-
$stubHash = computeStubHash($stubCode);
61-
$oldStubHash = extractStubHash($arginfoFile);
62-
if ($stubHash === $oldStubHash && !$context->forceParse) {
63-
/* Stub file did not change, do not regenerate. */
64-
return null;
60+
$stubCode = file_get_contents($stubFile);
61+
$stubHash = computeStubHash($stubCode);
62+
$oldStubHash = extractStubHash($arginfoFile);
63+
if ($stubHash === $oldStubHash && !$context->forceParse) {
64+
/* Stub file did not change, do not regenerate. */
65+
return null;
66+
}
6567
}
6668

67-
initPhpParser();
68-
$fileInfo = parseStubFile($stubCode);
69-
$constInfos = $fileInfo->getAllConstInfos();
70-
$context->allConstInfos = array_merge($context->allConstInfos, $constInfos);
69+
if (!$fileInfo = $context->parsedFiles[$stubFile] ?? null) {
70+
initPhpParser();
71+
$fileInfo = parseStubFile($stubCode ?? file_get_contents($stubFile));
72+
$context->parsedFiles[$stubFile] = $fileInfo;
73+
74+
foreach ($fileInfo->dependencies as $dependency) {
75+
// TODO add header search path for extensions?
76+
$prefixes = [dirname($stubFile) . "/", ""];
77+
foreach ($prefixes as $prefix) {
78+
$depFile = $prefix . $dependency;
79+
if (file_exists($depFile)) {
80+
break;
81+
}
82+
$depFile = null;
83+
}
84+
if (!$depFile) {
85+
throw new Exception("File $stubFile includes a file $dependency which does not exist");
86+
}
87+
processStubFile($depFile, $context, true);
88+
}
89+
90+
$constInfos = $fileInfo->getAllConstInfos();
91+
$context->allConstInfos = array_merge($context->allConstInfos, $constInfos);
92+
}
93+
94+
if ($includeOnly) {
95+
return $fileInfo;
96+
}
7197

7298
$arginfoCode = generateArgInfoCode(
7399
basename($stubFilenameWithoutExtension),
@@ -131,6 +157,8 @@ class Context {
131157
public $forceRegeneration = false;
132158
/** @var iterable<ConstInfo> */
133159
public iterable $allConstInfos = [];
160+
/** @var FileInfo[] */
161+
public array $parsedFiles = [];
134162
}
135163

136164
class ArrayType extends SimpleType {
@@ -2896,6 +2924,8 @@ private function appendInheritedMemberSectionToClassSynopsis(DOMDocument $doc, D
28962924
}
28972925

28982926
class FileInfo {
2927+
/** @var string[] */
2928+
public $dependencies = [];
28992929
/** @var ConstInfo[] */
29002930
public $constInfos = [];
29012931
/** @var FuncInfo[] */
@@ -3546,6 +3576,14 @@ function handleStatements(FileInfo $fileInfo, array $stmts, PrettyPrinterAbstrac
35463576
continue;
35473577
}
35483578

3579+
if ($stmt instanceof Stmt\Expression) {
3580+
$expr = $stmt->expr;
3581+
if ($expr instanceof Expr\Include_) {
3582+
$fileInfo->dependencies[] = (string)EvaluatedValue::createFromExpression($expr->expr, null, null, [])->value;
3583+
continue;
3584+
}
3585+
}
3586+
35493587
throw new Exception("Unexpected node {$stmt->getType()}");
35503588
}
35513589
}

ext/zend_test/test.stub.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
namespace {
66

7+
require "Zend/zend_attributes.stub.php";
8+
79
interface _ZendTestInterface
810
{
911
}

ext/zend_test/test_arginfo.h

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)