Skip to content
107 changes: 45 additions & 62 deletions build/gen_stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -770,9 +770,9 @@ public function toTypeMask(): string {
}

class ArgInfo {
const SEND_BY_VAL = "0";
const SEND_BY_REF = "1";
const SEND_PREFER_REF = "ZEND_SEND_PREFER_REF";
public const SEND_BY_VAL = "0";
public const SEND_BY_REF = "1";
public const SEND_PREFER_REF = "ZEND_SEND_PREFER_REF";

public /* readonly */ string $name;
public /* readonly */ string $sendBy;
Expand Down Expand Up @@ -859,19 +859,15 @@ public function __toString(): string;
public function getDeclarationName(): string;
}

interface ConstOrClassConstName extends VariableLikeName {
public function equals(ConstOrClassConstName $const): bool;
public function isClassConst(): bool;
public function isUnknown(): bool;
}

abstract class AbstractConstName implements ConstOrClassConstName
abstract class AbstractConstName implements VariableLikeName
{
public function equals(ConstOrClassConstName $const): bool
public function equals(AbstractConstName $const): bool
{
return $this->__toString() === $const->__toString();
}

abstract public function isClassConst(): bool;

public function isUnknown(): bool
{
return strtolower($this->__toString()) === "unknown";
Expand Down Expand Up @@ -1090,11 +1086,11 @@ public function isDestructor(): bool {
}

class ReturnInfo {
const REFCOUNT_0 = "0";
const REFCOUNT_1 = "1";
const REFCOUNT_N = "N";
public const REFCOUNT_0 = "0";
public const REFCOUNT_1 = "1";
public const REFCOUNT_N = "N";

const REFCOUNTS_NONSCALAR = [
public const REFCOUNTS_NONSCALAR = [
self::REFCOUNT_1,
self::REFCOUNT_N,
];
Expand Down Expand Up @@ -1428,9 +1424,7 @@ public function getFunctionEntry(): string {

if (!$php84MinimumCompatibility) {
$code .= "#else\n";
}

if (!$php84MinimumCompatibility) {
$flags = array_slice($flagsByPhpVersions, 0, 4, true);
$template = "\tZEND_RAW_FENTRY($zendName, $name, $argInfoName, %s)\n";
$flagsCode = generateVersionDependentFlagCode(
Expand All @@ -1439,9 +1433,7 @@ public function getFunctionEntry(): string {
$this->minimumPhpVersionIdCompatibility
);
$code .= implode("", $flagsCode);
}

if (!$php84MinimumCompatibility) {
$code .= "#endif\n";
}
}
Expand Down Expand Up @@ -2090,12 +2082,6 @@ public function __clone()
$this->args[$key] = clone $argInfo;
}
$this->return = clone $this->return;
foreach ($this->attributes as $key => $attribute) {
$this->attributes[$key] = clone $attribute;
}
foreach ($this->framelessFunctionInfos as $key => $framelessFunctionInfo) {
$this->framelessFunctionInfos[$key] = clone $framelessFunctionInfo;
}
}
}

Expand Down Expand Up @@ -2464,20 +2450,20 @@ protected function addFlagForVersionsAbove(array $flags, string $flag, int $mini

class ConstInfo extends VariableLike
{
public /* readonly */ ConstOrClassConstName $name;
public /* readonly */ AbstractConstName $name;
public /* readonly */ Expr $value;
public bool $isDeprecated;
public ?string $valueString;
public /* readonly */ ?string $valueString;
public /* readonly */ ?string $cond;
public ?string $cValue;
public bool $isUndocumentable;
public bool $isFileCacheAllowed;
public /* readonly */ ?string $cValue;
public /* readonly */ bool $isUndocumentable;
public /* readonly */ bool $isFileCacheAllowed;

/**
* @var AttributeInfo[] $attributes
*/
public function __construct(
ConstOrClassConstName $name,
AbstractConstName $name,
int $flags,
Expr $value,
?string $valueString,
Expand Down Expand Up @@ -3081,7 +3067,7 @@ private function getString(string $propName): array {
$include = array_merge($include, self::PHP_81_KNOWN);
break;
}
if (array_key_exists($propName,$include)) {
if (array_key_exists($propName, $include)) {
$knownStr = $include[$propName];
return [
'',
Expand Down Expand Up @@ -3145,9 +3131,6 @@ public function __clone()
if ($this->type) {
$this->type = clone $this->type;
}
foreach ($this->attributes as $key => $attribute) {
$this->attributes[$key] = clone $attribute;
}
}
}

Expand Down Expand Up @@ -3177,6 +3160,8 @@ public function getDeclaration(array $allConstInfos): string {
}
}

// Instances of AttributeInfo are immutable and do not need to be cloned
// when held by an object that is cloned
class AttributeInfo {
public /* readonly */ string $class;
/** @var \PhpParser\Node\Arg[] */
Expand Down Expand Up @@ -3256,7 +3241,7 @@ class ClassInfo {
public /* readonly */ array $enumCaseInfos;
public /* readonly */ ?string $cond;
public ?int $phpVersionIdMinimumCompatibility;
public bool $isUndocumentable;
public /* readonly */ bool $isUndocumentable;

/**
* @param AttributeInfo[] $attributes
Expand Down Expand Up @@ -3576,7 +3561,6 @@ public function discardInfoForOldPhpVersions(?int $phpVersionIdMinimumCompatibil
* @param iterable<ConstInfo> $allConstInfo
*/
public function getClassSynopsisDocument(array $classMap, array $allConstInfos): ?string {

$doc = new DOMDocument();
$doc->formatOutput = true;
$classSynopsis = $this->getClassSynopsisElement($doc, $classMap, $allConstInfos);
Expand All @@ -3594,7 +3578,6 @@ public function getClassSynopsisDocument(array $classMap, array $allConstInfos):
* @param array<string, ConstInfo> $allConstInfos
*/
public function getClassSynopsisElement(DOMDocument $doc, array $classMap, array $allConstInfos): ?DOMElement {

$classSynopsis = $doc->createElement("classsynopsis");
$classSynopsis->setAttribute("class", $this->type === "interface" ? "interface" : "class");

Expand Down Expand Up @@ -4006,10 +3989,6 @@ public function __clone()
foreach ($this->funcInfos as $key => $funcInfo) {
$this->funcInfos[$key] = clone $funcInfo;
}

foreach ($this->attributes as $key => $attribute) {
$this->attributes[$key] = clone $attribute;
}
}

/**
Expand Down Expand Up @@ -4229,16 +4208,17 @@ function parseDocComment(DocComment $comment): array {
return $tags;
}

// Instances of FramelessFunctionInfo are immutable and do not need to be cloned
// when held by an object that is cloned
class FramelessFunctionInfo {
public int $arity;
}
public /* readonly */ int $arity;

public function __construct(string $json) {
// FIXME: Should have some validation
$json = json_decode($json, true);

function parseFramelessFunctionInfo(string $json): FramelessFunctionInfo {
// FIXME: Should have some validation
$json = json_decode($json, true);
$framelessFunctionInfo = new FramelessFunctionInfo();
$framelessFunctionInfo->arity = $json["arity"];
return $framelessFunctionInfo;
$this->arity = $json["arity"];
}
}

function parseFunctionLike(
Expand Down Expand Up @@ -4322,7 +4302,7 @@ function parseFunctionLike(
break;

case 'frameless-function':
$framelessFunctionInfos[] = parseFramelessFunctionInfo($tag->getValue());
$framelessFunctionInfos[] = new FramelessFunctionInfo($tag->getValue());
break;
}
}
Expand Down Expand Up @@ -4439,7 +4419,7 @@ function parseFunctionLike(
*/
function parseConstLike(
PrettyPrinterAbstract $prettyPrinter,
ConstOrClassConstName $name,
AbstractConstName $name,
Node\Const_ $const,
int $flags,
?Node $type,
Expand Down Expand Up @@ -4592,14 +4572,12 @@ function parseClass(
?int $minimumPhpVersionIdCompatibility,
bool $isUndocumentable
): ClassInfo {
$flags = $class instanceof Class_ ? $class->flags : 0;
$comments = $class->getComments();
$alias = null;
$isDeprecated = false;
$isStrictProperties = false;
$isNotSerializable = false;
$allowsDynamicProperties = false;
$attributes = [];

if ($comments) {
$tags = parseDocComments($comments);
Expand Down Expand Up @@ -4660,7 +4638,7 @@ function parseClass(

return new ClassInfo(
$name,
$flags,
$class instanceof Class_ ? $class->flags : 0,
$classKind,
$alias,
$class instanceof Enum_ && $class->scalarType !== null
Expand Down Expand Up @@ -4883,7 +4861,15 @@ function handleStatements(FileInfo $fileInfo, array $stmts, PrettyPrinterAbstrac
}

$fileInfo->classInfos[] = parseClass(
$className, $stmt, $constInfos, $propertyInfos, $methodInfos, $enumCaseInfos, $cond, $fileInfo->getMinimumPhpVersionIdCompatibility(), $fileInfo->isUndocumentable
$className,
$stmt,
$constInfos,
$propertyInfos,
$methodInfos,
$enumCaseInfos,
$cond,
$fileInfo->getMinimumPhpVersionIdCompatibility(),
$fileInfo->isUndocumentable
);
continue;
}
Expand All @@ -4904,8 +4890,7 @@ function handleStatements(FileInfo $fileInfo, array $stmts, PrettyPrinterAbstrac
}

function parseStubFile(string $code): FileInfo {
$lexer = new PhpParser\Lexer\Emulative();
$parser = new PhpParser\Parser\Php7($lexer);
$parser = new PhpParser\Parser\Php7(new PhpParser\Lexer\Emulative());
$nodeTraverser = new PhpParser\NodeTraverser;
$nodeTraverser->addVisitor(new PhpParser\NodeVisitor\NameResolver);
$prettyPrinter = new class extends Standard {
Expand Down Expand Up @@ -5030,7 +5015,7 @@ function funcInfoToCode(FileInfo $fileInfo, FuncInfo $funcInfo): string {
} else {
$code .= sprintf(
"\tZEND_%s_OBJ_INFO%s(%s, %s, %s, %d%s)\n",
$argKind,$argDefaultKind, $argInfo->sendBy, $argInfo->name,
$argKind, $argDefaultKind, $argInfo->sendBy, $argInfo->name,
$simpleArgType->toEscapedName(), $argType->isNullable(),
$argInfo->hasProperDefaultValue() ? ", " . $argInfo->getDefaultValueAsArginfoString() : ""
);
Expand Down Expand Up @@ -5171,8 +5156,7 @@ static function (FuncInfo $funcInfo) use (&$generatedFuncInfos, $fileInfo) {
$framelessFunctionCode = generateCodeWithConditions(
$fileInfo->getAllFuncInfos(), "\n",
static function (FuncInfo $funcInfo) {
$code = $funcInfo->getFramelessDeclaration($funcInfo);
return $code;
return $funcInfo->getFramelessDeclaration($funcInfo);
}
);

Expand Down Expand Up @@ -5373,7 +5357,6 @@ function generatePropertyAttributeInitialization(

/** @param array<string, FuncInfo> $funcMap */
function generateOptimizerInfo(array $funcMap): string {

$code = "/* This is a generated file, edit the .stub.php files instead. */\n\n";

$code .= "static const func_info_t func_infos[] = {\n";
Expand Down