Skip to content

Commit b5f14f1

Browse files
committed
Fix GH-9967 Add support for generating custom function attributes in stubs
1 parent e7b6c2e commit b5f14f1

File tree

3 files changed

+41
-12
lines changed

3 files changed

+41
-12
lines changed

build/gen_stub.php

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1185,8 +1185,11 @@ class FuncInfo {
11851185
public int $numRequiredArgs;
11861186
public ?string $cond;
11871187
public bool $isUndocumentable;
1188+
/** @var AttributeInfo[] */
1189+
public array $attributes;
11881190

11891191
/**
1192+
* @param AttributeInfo[] $attributes
11901193
* @param ArgInfo[] $args
11911194
*/
11921195
public function __construct(
@@ -1202,7 +1205,8 @@ public function __construct(
12021205
ReturnInfo $return,
12031206
int $numRequiredArgs,
12041207
?string $cond,
1205-
bool $isUndocumentable
1208+
bool $isUndocumentable,
1209+
array $attributes
12061210
) {
12071211
$this->name = $name;
12081212
$this->classFlags = $classFlags;
@@ -1217,6 +1221,7 @@ public function __construct(
12171221
$this->numRequiredArgs = $numRequiredArgs;
12181222
$this->cond = $cond;
12191223
$this->isUndocumentable = $isUndocumentable;
1224+
$this->attributes = $attributes;
12201225
}
12211226

12221227
public function isMethod(): bool
@@ -1412,6 +1417,7 @@ public function getOptimizerInfo(): ?string {
14121417
}
14131418

14141419
public function discardInfoForOldPhpVersions(): void {
1420+
$this->attributes = [];
14151421
$this->return->type = null;
14161422
foreach ($this->args as $arg) {
14171423
$arg->type = null;
@@ -3221,17 +3227,24 @@ function parseFunctionLike(
32213227
}
32223228
}
32233229

3230+
$attributes = [];
3231+
foreach ($func->attrGroups as $attrGroup) {
3232+
foreach ($attrGroup->attrs as $attr) {
3233+
$attributes[] = new AttributeInfo($attr->name->toString(), $attr->args);
3234+
}
3235+
}
3236+
32243237
$varNameSet = [];
32253238
$args = [];
32263239
$numRequiredArgs = 0;
32273240
$foundVariadic = false;
32283241
foreach ($func->getParams() as $i => $param) {
32293242
$varName = $param->var->name;
32303243
$preferRef = !empty($paramMeta[$varName]['prefer-ref']);
3231-
$attributes = [];
3244+
$paramAttributes = [];
32323245
foreach ($param->attrGroups as $attrGroup) {
32333246
foreach ($attrGroup->attrs as $attr) {
3234-
$attributes[] = new AttributeInfo($attr->name->toString(), $attr->args);
3247+
$paramAttributes[] = new AttributeInfo($attr->name->toString(), $attr->args);
32353248
}
32363249
}
32373250
unset($paramMeta[$varName]);
@@ -3281,7 +3294,7 @@ function parseFunctionLike(
32813294
$type,
32823295
isset($docParamTypes[$varName]) ? Type::fromString($docParamTypes[$varName]) : null,
32833296
$param->default ? $prettyPrinter->prettyPrintExpr($param->default) : null,
3284-
$attributes
3297+
$paramAttributes
32853298
);
32863299
if (!$param->default && !$param->variadic) {
32873300
$numRequiredArgs = $i + 1;
@@ -3318,7 +3331,8 @@ function parseFunctionLike(
33183331
$return,
33193332
$numRequiredArgs,
33203333
$cond,
3321-
$isUndocumentable
3334+
$isUndocumentable,
3335+
$attributes
33223336
);
33233337
} catch (Exception $e) {
33243338
throw new Exception($name . "(): " .$e->getMessage());
@@ -4040,13 +4054,17 @@ function generateAttributeInitialization(iterable $funcInfos, iterable $allConst
40404054
static function (FuncInfo $funcInfo) use ($allConstInfos) {
40414055
$code = null;
40424056

4043-
foreach ($funcInfo->args as $index => $arg) {
4044-
if ($funcInfo->name instanceof MethodName) {
4045-
$functionTable = "&class_entry->function_table";
4046-
} else {
4047-
$functionTable = "CG(function_table)";
4048-
}
4057+
if ($funcInfo->name instanceof MethodName) {
4058+
$functionTable = "&class_entry->function_table";
4059+
} else {
4060+
$functionTable = "CG(function_table)";
4061+
}
4062+
4063+
foreach ($funcInfo->attributes as $attribute) {
4064+
$code .= $attribute->generateCode("zend_add_function_attribute(zend_hash_str_find_ptr($functionTable, \"" . $funcInfo->name->getNameForAttributes() . "\", sizeof(\"" . $funcInfo->name->getNameForAttributes() . "\") - 1)", $funcInfo->name->getMethodSynopsisFilename(), $allConstInfos);
4065+
}
40494066

4067+
foreach ($funcInfo->args as $index => $arg) {
40504068
foreach ($arg->attributes as $attribute) {
40514069
$code .= $attribute->generateCode("zend_add_parameter_attribute(zend_hash_str_find_ptr($functionTable, \"" . $funcInfo->name->getNameForAttributes() . "\", sizeof(\"" . $funcInfo->name->getNameForAttributes() . "\") - 1), $index", "{$funcInfo->name->getMethodSynopsisFilename()}_arg{$index}", $allConstInfos);
40524070
}

ext/zend_test/test.stub.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ trait _ZendTestTrait {
5151
/** @var mixed */
5252
public $testProp;
5353

54+
#[Attribute(Attribute::TARGET_METHOD)]
5455
public function testMethod(): bool {}
5556
}
5657

ext/zend_test/test_arginfo.h

Lines changed: 11 additions & 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)