Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Zend/zend_API.c
Original file line number Diff line number Diff line change
Expand Up @@ -2997,6 +2997,7 @@ ZEND_API void zend_convert_internal_arg_info(zend_arg_info *new_arg_info, const
new_arg_info->name = NULL;
new_arg_info->default_value = NULL;
}
new_arg_info->doc_comment = NULL;
new_arg_info->type = arg_info->type;
zend_convert_internal_arg_info_type(&new_arg_info->type, persistent);
}
Expand Down
2 changes: 2 additions & 0 deletions Zend/zend_compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -8024,6 +8024,7 @@ static void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32
} else {
arg_infos->type = (zend_type) ZEND_TYPE_INIT_CODE(fallback_return_type, 0, 0);
}
arg_infos->doc_comment = NULL;
arg_infos++;
op_array->fn_flags |= ZEND_ACC_HAS_RETURN_TYPE;

Expand Down Expand Up @@ -8122,6 +8123,7 @@ static void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32
arg_info->name = zend_string_copy(name);
arg_info->type = (zend_type) ZEND_TYPE_INIT_NONE(0);
arg_info->default_value = NULL;
arg_info->doc_comment = doc_comment_ast ? zend_string_copy(zend_ast_get_str(doc_comment_ast)) : NULL;

if (attributes_ast) {
zend_compile_attributes(
Expand Down
1 change: 1 addition & 0 deletions Zend/zend_compile.h
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,7 @@ typedef struct _zend_arg_info {
zend_string *name;
zend_type type;
zend_string *default_value;
zend_string *doc_comment;
} zend_arg_info;

/* the following structure repeats the layout of zend_internal_arg_info,
Expand Down
10 changes: 5 additions & 5 deletions Zend/zend_language_parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -817,13 +817,13 @@ optional_cpp_modifiers:

parameter:
optional_cpp_modifiers optional_type_without_static
is_reference is_variadic T_VARIABLE backup_doc_comment optional_property_hook_list
is_reference is_variadic T_VARIABLE optional_property_hook_list backup_doc_comment
{ $$ = zend_ast_create_ex(ZEND_AST_PARAM, $1 | $3 | $4, $2, $5, NULL,
NULL, $6 ? zend_ast_create_zval_from_str($6) : NULL, $7); }
NULL, $7 ? zend_ast_create_zval_from_str($7) : NULL, $6); }
| optional_cpp_modifiers optional_type_without_static
is_reference is_variadic T_VARIABLE backup_doc_comment '=' expr optional_property_hook_list
{ $$ = zend_ast_create_ex(ZEND_AST_PARAM, $1 | $3 | $4, $2, $5, $8,
NULL, $6 ? zend_ast_create_zval_from_str($6) : NULL, $9); }
is_reference is_variadic T_VARIABLE '=' expr optional_property_hook_list backup_doc_comment
{ $$ = zend_ast_create_ex(ZEND_AST_PARAM, $1 | $3 | $4, $2, $5, $7,
NULL, $9 ? zend_ast_create_zval_from_str($9) : NULL, $8); }
;

optional_type_without_static:
Expand Down
3 changes: 3 additions & 0 deletions Zend/zend_opcode.c
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,9 @@ ZEND_API void destroy_op_array(zend_op_array *op_array)
if (arg_info[i].name) {
zend_string_release_ex(arg_info[i].name, 0);
}
if (arg_info[i].doc_comment) {
zend_string_release_ex(arg_info[i].doc_comment, 0);
}
zend_type_release(arg_info[i].type, /* persistent */ false);
}
efree(arg_info);
Expand Down
3 changes: 3 additions & 0 deletions ext/opcache/zend_persist.c
Original file line number Diff line number Diff line change
Expand Up @@ -652,6 +652,9 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc
zend_accel_store_interned_string(arg_info[i].name);
}
zend_persist_type(&arg_info[i].type);
if (arg_info[i].doc_comment) {
zend_accel_store_interned_string(arg_info[i].doc_comment);
}
}
if (op_array->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
arg_info++;
Expand Down
3 changes: 3 additions & 0 deletions ext/opcache/zend_persist_calc.c
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,9 @@ static void zend_persist_op_array_calc_ex(zend_op_array *op_array)
ADD_INTERNED_STRING(arg_info[i].name);
}
zend_persist_type_calc(&arg_info[i].type);
if (arg_info[i].doc_comment) {
ADD_INTERNED_STRING(arg_info[i].doc_comment);
}
}
}

Expand Down
15 changes: 15 additions & 0 deletions ext/reflection/php_reflection.c
Original file line number Diff line number Diff line change
Expand Up @@ -2653,6 +2653,21 @@ ZEND_METHOD(ReflectionParameter, __toString)

/* }}} */

/* {{{ Returns the doc comment for this function */
Comment thread
chschneider marked this conversation as resolved.
Outdated
ZEND_METHOD(ReflectionParameter, getDocComment)
{
reflection_object *intern;
parameter_reference *param;

ZEND_PARSE_PARAMETERS_NONE();

GET_REFLECTION_OBJECT_PTR(param);
if (param->arg_info->doc_comment) {
RETURN_STR_COPY(param->arg_info->doc_comment);
}
RETURN_FALSE;
}

/* {{{ Returns this parameter's name */
ZEND_METHOD(ReflectionParameter, getName)
{
Expand Down
2 changes: 2 additions & 0 deletions ext/reflection/php_reflection.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,8 @@ public function __construct($function, int|string $param) {}

public function __toString(): string {}

public function getDocComment(): string|false {}

/** @tentative-return-type */
public function getName(): string {}

Expand Down
12 changes: 8 additions & 4 deletions ext/reflection/php_reflection_arginfo.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions ext/reflection/php_reflection_decl.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

194 changes: 194 additions & 0 deletions ext/reflection/tests/ReflectionParameter_getDocComment_basic.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
--TEST--
Comment thread
chschneider marked this conversation as resolved.
Test ReflectionParameter::getDocComment() usage.
--INI--
Comment thread
chschneider marked this conversation as resolved.
opcache.save_comments=1
--FILE--
<?php

class A
{
Comment thread
chschneider marked this conversation as resolved.
function func(
/**
* My Doc Comment for $a
*
*/
$a, $b, $c,
/**
* My Doc Comment for $d
*/
$d,
// Not a doc comment
/**Not a doc comment */
$e,
/**
* Doc comment for $f
*/
$f,
$g /** Doc comment for $g behind parameter */,
Comment thread
chschneider marked this conversation as resolved.
Outdated
/** Doc comment for $h */
$h /** Doc comment for $h behind parameter */,
) {}

public string $property {
set(
/** Doc Comment for property hook parameter $value */
string $value
) { $this->property = $value; }
}
}

function func(
/**
* My Doc Comment for $a
*
*/
$a, $b, $c,
/**
* My Doc Comment for $d
*/
$d,
// Not a doc comment
/**Not a doc comment */
$e,
/**
* Doc comment for $f
*/
$f,
$g /** Doc comment for $g behind parameter */,
/** Doc comment for $h */
$h /** Doc comment for $h behind parameter */,
) {}

$func = function(
Comment thread
chschneider marked this conversation as resolved.
Outdated
/**
* My Doc Comment for $a
*
*/
$a, $b, $c,
/**
* My Doc Comment for $d
*/
$d,
// Not a doc comment
/**Not a doc comment */
$e,
/**
* Doc comment for $f
*/
$f,
$g /** Doc comment for $g behind parameter */,
/** Doc comment for $h */
$h /** Doc comment for $h behind parameter */,
) {};

foreach([
'A::func' => (new ReflectionClass('A'))->getMethod('func'),
'func' => new ReflectionFunction('func'),
'closure' => new ReflectionFunction($func),
'property hook' => (new ReflectionClass('A'))->getProperty('property')->getHook(PropertyHookType::Set),
] as $function => $rc) {
$rps = $rc->getParameters();
foreach($rps as $rp) {
echo "\n---> Doc comment for $function parameter $" . $rp->getName() . ":\n";
var_dump($rp->getDocComment());
}
}

?>
--EXPECTF--
---> Doc comment for A::func parameter $a:
string(%d) "/**
* My Doc Comment for $a
*
*/"

Comment thread
chschneider marked this conversation as resolved.
---> Doc comment for A::func parameter $b:
bool(false)

---> Doc comment for A::func parameter $c:
bool(false)

---> Doc comment for A::func parameter $d:
string(%d) "/**
* My Doc Comment for $d
*/"

---> Doc comment for A::func parameter $e:
bool(false)

---> Doc comment for A::func parameter $f:
string(%d) "/**
* Doc comment for $f
*/"

---> Doc comment for A::func parameter $g:
string(%d) "/** Doc comment for $g behind parameter */"

---> Doc comment for A::func parameter $h:
string(%d) "/** Doc comment for $h behind parameter */"

---> Doc comment for func parameter $a:
string(%d) "/**
* My Doc Comment for $a
*
*/"

---> Doc comment for func parameter $b:
bool(false)

---> Doc comment for func parameter $c:
bool(false)

---> Doc comment for func parameter $d:
string(%d) "/**
* My Doc Comment for $d
*/"

---> Doc comment for func parameter $e:
bool(false)

---> Doc comment for func parameter $f:
string(%d) "/**
* Doc comment for $f
*/"

---> Doc comment for func parameter $g:
string(%d) "/** Doc comment for $g behind parameter */"

---> Doc comment for func parameter $h:
string(%d) "/** Doc comment for $h behind parameter */"

---> Doc comment for closure parameter $a:
string(%d) "/**
* My Doc Comment for $a
*
*/"

---> Doc comment for closure parameter $b:
bool(false)

---> Doc comment for closure parameter $c:
bool(false)

---> Doc comment for closure parameter $d:
string(%d) "/**
* My Doc Comment for $d
*/"

---> Doc comment for closure parameter $e:
bool(false)

---> Doc comment for closure parameter $f:
string(%d) "/**
* Doc comment for $f
*/"

---> Doc comment for closure parameter $g:
string(%d) "/** Doc comment for $g behind parameter */"

---> Doc comment for closure parameter $h:
string(%d) "/** Doc comment for $h behind parameter */"

---> Doc comment for property hook parameter $value:
string(%d) "/** Doc Comment for property hook parameter $value */"