diff --git a/build/gen_stub.php b/build/gen_stub.php
index ca14022cc5241..c64aa65530f97 100755
--- a/build/gen_stub.php
+++ b/build/gen_stub.php
@@ -43,6 +43,17 @@ function reportFilePutContents(string $filename, string $content): void {
}
}
+if (!function_exists('array_any')) {
+ function array_any(array $array, callable $callback): bool {
+ foreach ($array as $key => $value) {
+ if ($callback($value, $key)) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
+
/**
* @return FileInfo[]
*/
@@ -133,9 +144,8 @@ function processStubFile(string $stubFile, Context $context, bool $includeOnly =
return $fileInfo;
}
- [$arginfoCode, $declCode] = generateArgInfoCode(
+ [$arginfoCode, $declCode] = $fileInfo->generateArgInfoCode(
basename($stubFilenameWithoutExtension),
- $fileInfo,
$context->allConstInfos,
$stubHash
);
@@ -151,9 +161,8 @@ function processStubFile(string $stubFile, Context $context, bool $includeOnly =
if ($fileInfo->shouldGenerateLegacyArginfo()) {
$legacyFileInfo = $fileInfo->getLegacyVersion();
- [$arginfoCode] = generateArgInfoCode(
+ [$arginfoCode] = $legacyFileInfo->generateArgInfoCode(
basename($stubFilenameWithoutExtension),
- $legacyFileInfo,
$context->allConstInfos,
$stubHash
);
@@ -599,23 +608,11 @@ private function __construct(array $types, bool $isIntersection) {
}
public function isScalar(): bool {
- foreach ($this->types as $type) {
- if (!$type->isScalar()) {
- return false;
- }
- }
-
- return true;
+ return !array_any($this->types, static fn (SimpleType $type): bool => !$type->isScalar());
}
public function isNullable(): bool {
- foreach ($this->types as $type) {
- if ($type->isNull()) {
- return true;
- }
- }
-
- return false;
+ return array_any($this->types, static fn (SimpleType $type): bool => $type->isNull());
}
public function tryToSimpleType(): ?SimpleType {
@@ -1237,12 +1234,10 @@ public function addForVersionsAbove(string $flag, int $minimumVersionId): void {
}
public function isEmpty(): bool {
- foreach (ALL_PHP_VERSION_IDS as $version) {
- if ($this->flagsByVersion[$version] !== []) {
- return false;
- }
- }
- return true;
+ return !array_any(
+ ALL_PHP_VERSION_IDS,
+ fn (int $version): bool => $this->flagsByVersion[$version] !== []
+ );
}
public function generateVersionDependentFlagCode(
@@ -1439,13 +1434,10 @@ private function getModifierNames(): array
private function hasParamWithUnknownDefaultValue(): bool
{
- foreach ($this->args as $arg) {
- if ($arg->defaultValue && !$arg->hasProperDefaultValue()) {
- return true;
- }
- }
-
- return false;
+ return array_any(
+ $this->args,
+ static fn (ArgInfo $arg): bool => $arg->defaultValue && !$arg->hasProperDefaultValue()
+ );
}
private function equalsApartFromNameAndRefcount(FuncInfo $other): bool {
@@ -1666,12 +1658,11 @@ private function getArginfoFlagsByPhpVersions(): VersionFlags
$flags[] = "ZEND_ACC_DEPRECATED";
}
- foreach ($this->attributes as $attr) {
- switch ($attr->class) {
- case "Deprecated":
- $flags[] = "ZEND_ACC_DEPRECATED";
- break;
- }
+ if (array_any(
+ $this->attributes,
+ static fn (AttributeInfo $attr): bool => $attr->class === "Deprecated"
+ )) {
+ $flags[] = "ZEND_ACC_DEPRECATED";
}
$flags = new VersionFlags($flags);
@@ -1680,12 +1671,11 @@ private function getArginfoFlagsByPhpVersions(): VersionFlags
$flags->addForVersionsAbove("ZEND_ACC_COMPILE_TIME_EVAL", PHP_82_VERSION_ID);
}
- foreach ($this->attributes as $attr) {
- switch ($attr->class) {
- case "NoDiscard":
- $flags->addForVersionsAbove("ZEND_ACC_NODISCARD", PHP_85_VERSION_ID);
- break;
- }
+ if (array_any(
+ $this->attributes,
+ static fn (AttributeInfo $attr): bool => $attr->class === "NoDiscard"
+ )) {
+ $flags->addForVersionsAbove("ZEND_ACC_NODISCARD", PHP_85_VERSION_ID);
}
return $flags;
@@ -1882,56 +1872,56 @@ private function getParameterSection(DOMDocument $doc): DOMElement {
$noParamEntity = $doc->createEntityReference('no.function.parameters');
$parametersRefSec->appendChild($noParamEntity);
return $parametersRefSec;
- } else {
- $parametersContainer = $doc->createDocumentFragment();
-
- $parametersContainer->appendChild(new DOMText("\n "));
- $parametersList = $doc->createElement('variablelist');
- $parametersContainer->appendChild($parametersList);
-
- /*
-
- name
-
-
- Description.
-
-
-
- */
- foreach ($this->args as $arg) {
- $parameter = $doc->createElement('parameter', $arg->name);
- $parameterTerm = $doc->createElement('term');
- $parameterTerm->appendChild($parameter);
-
- $listItemPara = $doc->createElement('simpara');
- $listItemPara->append(
- "\n ",
- "Description.",
- "\n ",
- );
+ }
+ $parametersContainer = $doc->createDocumentFragment();
+
+ $parametersContainer->appendChild(new DOMText("\n "));
+ $parametersList = $doc->createElement('variablelist');
+ $parametersContainer->appendChild($parametersList);
+
+ /*
+
+ name
+
+
+ Description.
+
+
+
+ */
+ foreach ($this->args as $arg) {
+ $parameter = $doc->createElement('parameter', $arg->name);
+ $parameterTerm = $doc->createElement('term');
+ $parameterTerm->appendChild($parameter);
+
+ $listItemPara = $doc->createElement('simpara');
+ $listItemPara->append(
+ "\n ",
+ "Description.",
+ "\n ",
+ );
- $parameterEntryListItem = $doc->createElement('listitem');
- $parameterEntryListItem->append(
- "\n ",
- $listItemPara,
- "\n ",
- );
+ $parameterEntryListItem = $doc->createElement('listitem');
+ $parameterEntryListItem->append(
+ "\n ",
+ $listItemPara,
+ "\n ",
+ );
- $parameterEntry = $doc->createElement('varlistentry');
- $parameterEntry->append(
- "\n ",
- $parameterTerm,
- "\n ",
- $parameterEntryListItem,
- "\n ",
- );
+ $parameterEntry = $doc->createElement('varlistentry');
+ $parameterEntry->append(
+ "\n ",
+ $parameterTerm,
+ "\n ",
+ $parameterEntryListItem,
+ "\n ",
+ );
- $parametersList->appendChild(new DOMText("\n "));
- $parametersList->appendChild($parameterEntry);
- }
- $parametersList->appendChild(new DOMText("\n "));
+ $parametersList->appendChild(new DOMText("\n "));
+ $parametersList->appendChild($parameterEntry);
}
+ $parametersList->appendChild(new DOMText("\n "));
+
$parametersContainer->appendChild(new DOMText("\n "));
$parametersRefSec->appendChild($parametersContainer);
$parametersRefSec->appendChild(new DOMText("\n "));
@@ -2234,11 +2224,11 @@ public function findEquivalent(array $generatedFuncInfos): ?FuncInfo {
return null;
}
- public function toArgInfoCode(?int $minPHPCompatability): string {
+ public function toArgInfoCode(?int $minPHPCompatibility): string {
$code = $this->return->beginArgInfo(
$this->getArgInfoName(),
$this->numRequiredArgs,
- $minPHPCompatability === null || $minPHPCompatability >= PHP_81_VERSION_ID
+ $minPHPCompatibility === null || $minPHPCompatibility >= PHP_81_VERSION_ID
);
foreach ($this->args as $argInfo) {
@@ -2503,8 +2493,6 @@ protected function getFlagsByPhpVersion(): VersionFlags
protected function getTypeCode(string $variableLikeName, string &$code): string
{
$variableLikeType = $this->getVariableTypeName();
-
- $typeCode = "";
if ($this->type) {
$arginfoType = $this->type->toArginfoType();
if ($arginfoType->hasClassType()) {
@@ -2531,22 +2519,17 @@ protected function getTypeCode(string $variableLikeName, string &$code): string
} else {
$code .= "\tzend_type {$variableLikeType}_{$variableLikeName}_type = ZEND_TYPE_INIT_UNION({$variableLikeType}_{$variableLikeName}_type_list, $typeMaskCode);\n";
}
- $typeCode = "{$variableLikeType}_{$variableLikeName}_type";
- } else {
- $escapedClassName = $arginfoType->classTypes[0]->toEscapedName();
- $varEscapedClassName = $arginfoType->classTypes[0]->toVarEscapedName();
- $code .= "\tzend_string *{$variableLikeType}_{$variableLikeName}_class_{$varEscapedClassName} = zend_string_init(\"{$escapedClassName}\", sizeof(\"{$escapedClassName}\")-1, 1);\n";
-
- $typeCode = "(zend_type) ZEND_TYPE_INIT_CLASS({$variableLikeType}_{$variableLikeName}_class_{$varEscapedClassName}, 0, " . $arginfoType->toTypeMask() . ")";
+ return "{$variableLikeType}_{$variableLikeName}_type";
}
- } else {
- $typeCode = "(zend_type) ZEND_TYPE_INIT_MASK(" . $arginfoType->toTypeMask() . ")";
+ $escapedClassName = $arginfoType->classTypes[0]->toEscapedName();
+ $varEscapedClassName = $arginfoType->classTypes[0]->toVarEscapedName();
+ $code .= "\tzend_string *{$variableLikeType}_{$variableLikeName}_class_{$varEscapedClassName} = zend_string_init(\"{$escapedClassName}\", sizeof(\"{$escapedClassName}\")-1, 1);\n";
+
+ return "(zend_type) ZEND_TYPE_INIT_CLASS({$variableLikeType}_{$variableLikeName}_class_{$varEscapedClassName}, 0, " . $arginfoType->toTypeMask() . ")";
}
- } else {
- $typeCode = "(zend_type) ZEND_TYPE_INIT_NONE(0)";
+ return "(zend_type) ZEND_TYPE_INIT_MASK(" . $arginfoType->toTypeMask() . ")";
}
-
- return $typeCode;
+ return "(zend_type) ZEND_TYPE_INIT_NONE(0)";
}
/** @param array $allConstInfos */
@@ -2635,11 +2618,11 @@ public function __construct(
?ExposedDocComment $exposedDocComment,
bool $isFileCacheAllowed
) {
- foreach ($attributes as $attr) {
- if ($attr->class === "Deprecated") {
- $isDeprecated = true;
- break;
- }
+ if (array_any(
+ $attributes,
+ static fn (AttributeInfo $attr): bool => $attr->class === "Deprecated"
+ )) {
+ $isDeprecated = true;
}
$this->name = $name;
@@ -2759,7 +2742,7 @@ public function getDeclaration(array $allConstInfos): string
// Condition will be added by generateCodeWithConditions()
if ($this->name instanceof ClassConstName) {
- $code = $this->getClassConstDeclaration($value, $allConstInfos);
+ $code = $this->getClassConstDeclaration($value);
} else {
$code = $this->getGlobalConstDeclaration($value);
}
@@ -2820,12 +2803,10 @@ private function getGlobalConstDeclaration(EvaluatedValue $value): string
throw new Exception("Unimplemented constant type");
}
- /** @param array $allConstInfos */
- private function getClassConstDeclaration(EvaluatedValue $value, array $allConstInfos): string
+ private function getClassConstDeclaration(EvaluatedValue $value): string
{
$constName = $this->name->getDeclarationName();
- // TODO $allConstInfos is unused
$zvalCode = $value->initializeZval("const_{$constName}_value");
$code = "\n" . $zvalCode;
@@ -3323,14 +3304,13 @@ public function __construct(string $name, ?Expr $value) {
public function getDeclaration(array $allConstInfos): string {
$escapedName = addslashes($this->name);
if ($this->value === null) {
- $code = "\n\tzend_enum_add_case_cstr(class_entry, \"$escapedName\", NULL);\n";
- } else {
- $value = EvaluatedValue::createFromExpression($this->value, null, null, $allConstInfos);
-
- $zvalName = "enum_case_{$escapedName}_value";
- $code = "\n" . $value->initializeZval($zvalName);
- $code .= "\tzend_enum_add_case_cstr(class_entry, \"$escapedName\", &$zvalName);\n";
+ return "\n\tzend_enum_add_case_cstr(class_entry, \"$escapedName\", NULL);\n";
}
+ $value = EvaluatedValue::createFromExpression($this->value, null, null, $allConstInfos);
+
+ $zvalName = "enum_case_{$escapedName}_value";
+ $code = "\n" . $value->initializeZval($zvalName);
+ $code .= "\tzend_enum_add_case_cstr(class_entry, \"$escapedName\", &$zvalName);\n";
return $code;
}
@@ -3760,11 +3740,11 @@ private function getFlagsByPhpVersion(): VersionFlags
$flags->addForVersionsAbove("ZEND_ACC_READONLY_CLASS", PHP_82_VERSION_ID);
}
- foreach ($this->attributes as $attr) {
- if ($attr->class === "AllowDynamicProperties") {
- $flags->addForVersionsAbove("ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES", PHP_82_VERSION_ID);
- break;
- }
+ if (array_any(
+ $this->attributes,
+ static fn (AttributeInfo $attr): bool => $attr->class === "AllowDynamicProperties"
+ )) {
+ $flags->addForVersionsAbove("ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES", PHP_82_VERSION_ID);
}
return $flags;
@@ -4171,46 +4151,34 @@ private function isException(array $classMap): bool
private function hasConstructor(): bool
{
- foreach ($this->funcInfos as $funcInfo) {
- if ($funcInfo->name->isConstructor()) {
- return true;
- }
- }
-
- return false;
+ return array_any(
+ $this->funcInfos,
+ static fn (FuncInfo $funcInfo): bool => $funcInfo->name->isConstructor()
+ );
}
private function hasNonPrivateConstructor(): bool
{
- foreach ($this->funcInfos as $funcInfo) {
- if ($funcInfo->name->isConstructor() && !($funcInfo->flags & Modifiers::PRIVATE)) {
- return true;
- }
- }
-
- return false;
+ return array_any(
+ $this->funcInfos,
+ static fn (FuncInfo $funcInfo): bool => $funcInfo->name->isConstructor() && !($funcInfo->flags & Modifiers::PRIVATE)
+ );
}
private function hasDestructor(): bool
{
- foreach ($this->funcInfos as $funcInfo) {
- if ($funcInfo->name->isDestructor()) {
- return true;
- }
- }
-
- return false;
+ return array_any(
+ $this->funcInfos,
+ static fn (FuncInfo $funcInfo): bool => $funcInfo->name->isDestructor()
+ );
}
private function hasMethods(): bool
{
- foreach ($this->funcInfos as $funcInfo) {
- if (!$funcInfo->name->isConstructor() && !$funcInfo->name->isDestructor()) {
- return true;
- }
- }
-
- return false;
+ return array_any(
+ $this->funcInfos,
+ static fn (FuncInfo $funcInfo): bool => !$funcInfo->name->isConstructor() && !$funcInfo->name->isDestructor()
+ );
}
public function getNamespace(): ?string {
@@ -4292,13 +4260,13 @@ class FileInfo {
/** @var ConstInfo[] */
public array $constInfos = [];
/** @var FuncInfo[] */
- public array $funcInfos = [];
+ private array $funcInfos = [];
/** @var ClassInfo[] */
public array $classInfos = [];
- public bool $generateFunctionEntries = false;
- public string $declarationPrefix = "";
- public bool $generateClassEntries = false;
- public bool $generateCEnums = false;
+ private bool $generateFunctionEntries = false;
+ private string $declarationPrefix = "";
+ private bool $generateClassEntries = false;
+ private bool $generateCEnums = false;
private bool $isUndocumentable = false;
private bool $legacyArginfoGeneration = false;
private ?int $minimumPhpVersionIdCompatibility = null;
@@ -4377,7 +4345,7 @@ public function __clone()
}
}
- public function getMinimumPhpVersionIdCompatibility(): ?int {
+ private function getMinimumPhpVersionIdCompatibility(): ?int {
// Non-legacy arginfo files are always PHP 8.0+ compatible
if (!$this->legacyArginfoGeneration &&
$this->minimumPhpVersionIdCompatibility !== null &&
@@ -4641,6 +4609,130 @@ public function generateCDeclarations(): string {
return $code;
}
+
+
+ /**
+ * @param array $allConstInfos
+ * @return array{string, string}
+ */
+ public function generateArgInfoCode(
+ string $stubFilenameWithoutExtension,
+ array $allConstInfos,
+ string $stubHash
+ ): array {
+ $code = "";
+
+ $generatedFuncInfos = [];
+
+ $argInfoCode = generateCodeWithConditions(
+ $this->getAllFuncInfos(), "\n",
+ function (FuncInfo $funcInfo) use (&$generatedFuncInfos) {
+ /* If there already is an equivalent arginfo structure, only emit a #define */
+ if ($generatedFuncInfo = $funcInfo->findEquivalent($generatedFuncInfos)) {
+ $code = sprintf(
+ "#define %s %s\n",
+ $funcInfo->getArgInfoName(), $generatedFuncInfo->getArgInfoName()
+ );
+ } else {
+ $code = $funcInfo->toArgInfoCode($this->getMinimumPhpVersionIdCompatibility());
+ }
+
+ $generatedFuncInfos[] = $funcInfo;
+ return $code;
+ }
+ );
+
+ if ($argInfoCode !== "") {
+ $code .= "$argInfoCode\n";
+ }
+
+ if ($this->generateFunctionEntries) {
+ $framelessFunctionCode = generateCodeWithConditions(
+ $this->getAllFuncInfos(), "\n",
+ static function (FuncInfo $funcInfo) {
+ return $funcInfo->getFramelessDeclaration();
+ }
+ );
+
+ if ($framelessFunctionCode !== "") {
+ $code .= "$framelessFunctionCode\n";
+ }
+
+ $generatedFunctionDeclarations = [];
+ $code .= generateCodeWithConditions(
+ $this->getAllFuncInfos(), "",
+ function (FuncInfo $funcInfo) use (&$generatedFunctionDeclarations) {
+ $key = $funcInfo->getDeclarationKey();
+ if (isset($generatedFunctionDeclarations[$key])) {
+ return null;
+ }
+
+ $generatedFunctionDeclarations[$key] = true;
+ return $this->declarationPrefix . $funcInfo->getDeclaration();
+ }
+ );
+
+ $code .= generateFunctionEntries(null, $this->funcInfos);
+
+ foreach ($this->classInfos as $classInfo) {
+ $code .= generateFunctionEntries($classInfo->name, $classInfo->funcInfos, $classInfo->cond);
+ }
+ }
+
+ $php80MinimumCompatibility = $this->getMinimumPhpVersionIdCompatibility() === null || $this->getMinimumPhpVersionIdCompatibility() >= PHP_80_VERSION_ID;
+
+ if ($this->generateClassEntries) {
+ $declaredStrings = [];
+ $attributeInitializationCode = generateFunctionAttributeInitialization($this->funcInfos, $allConstInfos, $this->getMinimumPhpVersionIdCompatibility(), null, $declaredStrings);
+ $attributeInitializationCode .= generateGlobalConstantAttributeInitialization($this->constInfos, $allConstInfos, $this->getMinimumPhpVersionIdCompatibility(), null, $declaredStrings);
+ if ($attributeInitializationCode) {
+ if (!$php80MinimumCompatibility) {
+ $attributeInitializationCode = "\n#if (PHP_VERSION_ID >= " . PHP_80_VERSION_ID . ")" . $attributeInitializationCode . "#endif\n";
+ }
+ }
+
+ if ($attributeInitializationCode !== "" || !empty($this->constInfos)) {
+ $code .= "\nstatic void register_{$stubFilenameWithoutExtension}_symbols(int module_number)\n";
+ $code .= "{\n";
+
+ $code .= generateCodeWithConditions(
+ $this->constInfos,
+ '',
+ static fn (ConstInfo $constInfo): string => $constInfo->getDeclaration($allConstInfos)
+ );
+
+ if ($attributeInitializationCode !== "" && $this->constInfos) {
+ $code .= "\n";
+ }
+
+ $code .= $attributeInitializationCode;
+ $code .= "}\n";
+ }
+
+ $code .= $this->generateClassEntryCode($allConstInfos);
+ }
+
+ $hasDeclFile = false;
+ $declCode = $this->generateCDeclarations();
+ if ($declCode !== '') {
+ $hasDeclFile = true;
+ $headerName = "ZEND_" . strtoupper($stubFilenameWithoutExtension) . "_DECL_{$stubHash}_H";
+ $declCode = "/* This is a generated file, edit {$stubFilenameWithoutExtension}.stub.php instead.\n"
+ . " * Stub hash: $stubHash */\n"
+ . "\n"
+ . "#ifndef {$headerName}\n"
+ . "#define {$headerName}\n"
+ . $declCode . "\n"
+ . "#endif /* {$headerName} */\n";
+ }
+
+ $code = "/* This is a generated file, edit {$stubFilenameWithoutExtension}.stub.php instead.\n"
+ . " * Stub hash: $stubHash"
+ . ($hasDeclFile ? "\n * Has decl header: yes */\n" : " */\n")
+ . $code;
+
+ return [$code, $declCode];
+ }
}
class DocCommentTag {
@@ -5140,7 +5232,6 @@ function parseClass(
): ClassInfo {
$comments = $class->getComments();
$alias = null;
- $allowsDynamicProperties = false;
$tags = DocCommentTag::parseDocComments($comments);
$tagMap = DocCommentTag::makeTagMap($tags);
@@ -5156,13 +5247,10 @@ function parseClass(
}
$attributes = AttributeInfo::createFromGroups($class->attrGroups);
- foreach ($attributes as $attribute) {
- switch ($attribute->class) {
- case 'AllowDynamicProperties':
- $allowsDynamicProperties = true;
- break 2;
- }
- }
+ $allowsDynamicProperties = array_any(
+ $attributes,
+ static fn (AttributeInfo $attribute): bool => $attribute->class === 'AllowDynamicProperties'
+ );
if ($isStrictProperties && $allowsDynamicProperties) {
throw new Exception("A class may not have '@strict-properties' and '#[\\AllowDynamicProperties]' at the same time.");
@@ -5274,130 +5362,6 @@ function generateCodeWithConditions(
return $code;
}
-/**
- * @param array $allConstInfos
- * @return array{string, string}
- */
-function generateArgInfoCode(
- string $stubFilenameWithoutExtension,
- FileInfo $fileInfo,
- array $allConstInfos,
- string $stubHash
-): array {
- $code = "";
-
- $generatedFuncInfos = [];
-
- $argInfoCode = generateCodeWithConditions(
- $fileInfo->getAllFuncInfos(), "\n",
- static function (FuncInfo $funcInfo) use (&$generatedFuncInfos, $fileInfo) {
- /* If there already is an equivalent arginfo structure, only emit a #define */
- if ($generatedFuncInfo = $funcInfo->findEquivalent($generatedFuncInfos)) {
- $code = sprintf(
- "#define %s %s\n",
- $funcInfo->getArgInfoName(), $generatedFuncInfo->getArgInfoName()
- );
- } else {
- $code = $funcInfo->toArgInfoCode($fileInfo->getMinimumPhpVersionIdCompatibility());
- }
-
- $generatedFuncInfos[] = $funcInfo;
- return $code;
- }
- );
-
- if ($argInfoCode !== "") {
- $code .= "$argInfoCode\n";
- }
-
- if ($fileInfo->generateFunctionEntries) {
- $framelessFunctionCode = generateCodeWithConditions(
- $fileInfo->getAllFuncInfos(), "\n",
- static function (FuncInfo $funcInfo) {
- return $funcInfo->getFramelessDeclaration();
- }
- );
-
- if ($framelessFunctionCode !== "") {
- $code .= "$framelessFunctionCode\n";
- }
-
- $generatedFunctionDeclarations = [];
- $code .= generateCodeWithConditions(
- $fileInfo->getAllFuncInfos(), "",
- static function (FuncInfo $funcInfo) use ($fileInfo, &$generatedFunctionDeclarations) {
- $key = $funcInfo->getDeclarationKey();
- if (isset($generatedFunctionDeclarations[$key])) {
- return null;
- }
-
- $generatedFunctionDeclarations[$key] = true;
- return $fileInfo->declarationPrefix . $funcInfo->getDeclaration();
- }
- );
-
- $code .= generateFunctionEntries(null, $fileInfo->funcInfos);
-
- foreach ($fileInfo->classInfos as $classInfo) {
- $code .= generateFunctionEntries($classInfo->name, $classInfo->funcInfos, $classInfo->cond);
- }
- }
-
- $php80MinimumCompatibility = $fileInfo->getMinimumPhpVersionIdCompatibility() === null || $fileInfo->getMinimumPhpVersionIdCompatibility() >= PHP_80_VERSION_ID;
-
- if ($fileInfo->generateClassEntries) {
- $declaredStrings = [];
- $attributeInitializationCode = generateFunctionAttributeInitialization($fileInfo->funcInfos, $allConstInfos, $fileInfo->getMinimumPhpVersionIdCompatibility(), null, $declaredStrings);
- $attributeInitializationCode .= generateGlobalConstantAttributeInitialization($fileInfo->constInfos, $allConstInfos, $fileInfo->getMinimumPhpVersionIdCompatibility(), null, $declaredStrings);
- if ($attributeInitializationCode) {
- if (!$php80MinimumCompatibility) {
- $attributeInitializationCode = "\n#if (PHP_VERSION_ID >= " . PHP_80_VERSION_ID . ")" . $attributeInitializationCode . "#endif\n";
- }
- }
-
- if ($attributeInitializationCode !== "" || !empty($fileInfo->constInfos)) {
- $code .= "\nstatic void register_{$stubFilenameWithoutExtension}_symbols(int module_number)\n";
- $code .= "{\n";
-
- $code .= generateCodeWithConditions(
- $fileInfo->constInfos,
- '',
- static fn (ConstInfo $constInfo): string => $constInfo->getDeclaration($allConstInfos)
- );
-
- if ($attributeInitializationCode !== "" && $fileInfo->constInfos) {
- $code .= "\n";
- }
-
- $code .= $attributeInitializationCode;
- $code .= "}\n";
- }
-
- $code .= $fileInfo->generateClassEntryCode($allConstInfos);
- }
-
- $hasDeclFile = false;
- $declCode = $fileInfo->generateCDeclarations();
- if ($declCode !== '') {
- $hasDeclFile = true;
- $headerName = "ZEND_" . strtoupper($stubFilenameWithoutExtension) . "_DECL_{$stubHash}_H";
- $declCode = "/* This is a generated file, edit {$stubFilenameWithoutExtension}.stub.php instead.\n"
- . " * Stub hash: $stubHash */\n"
- . "\n"
- . "#ifndef {$headerName}\n"
- . "#define {$headerName}\n"
- . $declCode . "\n"
- . "#endif /* {$headerName} */\n";
- }
-
- $code = "/* This is a generated file, edit {$stubFilenameWithoutExtension}.stub.php instead.\n"
- . " * Stub hash: $stubHash"
- . ($hasDeclFile ? "\n * Has decl header: yes */\n" : " */\n")
- . $code;
-
- return [$code, $declCode];
-}
-
/** @param FuncInfo[] $funcInfos */
function generateFunctionEntries(?Name $className, array $funcInfos, ?string $cond = null): string {
// No need to add anything if there are no function entries