diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2020-03-24 13:18:28 +0100 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2020-06-05 15:15:51 +0200 |
commit | 064b4644484d38e9dce40aef7e8e0e8190e9d863 (patch) | |
tree | ceb34fd4bc375ea0accdf3f8b1b15c389c7e103a /ext/reflection | |
parent | 91f283a0bfc6792d84fb9a6361e21f6f33769c4d (diff) | |
download | php-git-064b4644484d38e9dce40aef7e8e0e8190e9d863.tar.gz |
Implement "Constructor Promotion" RFC
RFC: https://wiki.php.net/rfc/constructor_promotion
Closes GH-5291.
Diffstat (limited to 'ext/reflection')
-rw-r--r-- | ext/reflection/php_reflection.c | 24 | ||||
-rw-r--r-- | ext/reflection/php_reflection.stub.php | 4 | ||||
-rw-r--r-- | ext/reflection/php_reflection_arginfo.h | 12 | ||||
-rw-r--r-- | ext/reflection/tests/bug71767.phpt | 9 | ||||
-rw-r--r-- | ext/reflection/tests/constructor_promotion.phpt | 70 |
5 files changed, 117 insertions, 2 deletions
diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 6d4f257eb4..d986f828f5 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -2870,6 +2870,22 @@ ZEND_METHOD(ReflectionParameter, isVariadic) } /* }}} */ +/* {{{ proto public bool ReflectionParameter::isPromoted() + Returns this constructor parameter has been promoted to a property */ +ZEND_METHOD(ReflectionParameter, isPromoted) +{ + reflection_object *intern; + parameter_reference *param; + + if (zend_parse_parameters_none() == FAILURE) { + RETURN_THROWS(); + } + GET_REFLECTION_OBJECT_PTR(param); + + RETVAL_BOOL(ZEND_ARG_IS_PROMOTED(param->arg_info)); +} +/* }}} */ + /* {{{ proto public bool ReflectionType::allowsNull() Returns whether parameter MAY be null */ ZEND_METHOD(ReflectionType, allowsNull) @@ -5461,6 +5477,14 @@ ZEND_METHOD(ReflectionProperty, isDefault) } /* }}} */ +/* {{{ proto public bool ReflectionProperty::isPromoted() + Returns whether this property has been promoted from a constructor */ +ZEND_METHOD(ReflectionProperty, isPromoted) +{ + _property_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_PROMOTED); +} +/* }}} */ + /* {{{ proto public int ReflectionProperty::getModifiers() Returns a bitfield of the access modifiers for this property */ ZEND_METHOD(ReflectionProperty, getModifiers) diff --git a/ext/reflection/php_reflection.stub.php b/ext/reflection/php_reflection.stub.php index c27f971c07..e3d3fee52c 100644 --- a/ext/reflection/php_reflection.stub.php +++ b/ext/reflection/php_reflection.stub.php @@ -413,6 +413,8 @@ class ReflectionProperty implements Reflector /** @return bool */ public function isDefault() {} + public function isPromoted(): bool {} + /** @return int */ public function getModifiers() {} @@ -553,6 +555,8 @@ class ReflectionParameter implements Reflector /** @return bool */ public function isVariadic() {} + public function isPromoted(): bool {} + /** @return ReflectionAttribute[] */ public function getAttributes(?string $name = null, int $flags = 0): array {} } diff --git a/ext/reflection/php_reflection_arginfo.h b/ext/reflection/php_reflection_arginfo.h index 3dec73ec8b..e5ed4742ff 100644 --- a/ext/reflection/php_reflection_arginfo.h +++ b/ext/reflection/php_reflection_arginfo.h @@ -312,6 +312,9 @@ ZEND_END_ARG_INFO() #define arginfo_class_ReflectionProperty_isDefault arginfo_class_ReflectionFunctionAbstract___clone +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_ReflectionProperty_isPromoted, 0, 0, _IS_BOOL, 0) +ZEND_END_ARG_INFO() + #define arginfo_class_ReflectionProperty_getModifiers arginfo_class_ReflectionFunctionAbstract___clone #define arginfo_class_ReflectionProperty_getDeclaringClass arginfo_class_ReflectionFunctionAbstract___clone @@ -324,8 +327,7 @@ ZEND_END_ARG_INFO() #define arginfo_class_ReflectionProperty_hasType arginfo_class_ReflectionFunctionAbstract___clone -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_ReflectionProperty_hasDefaultValue, 0, 0, _IS_BOOL, 0) -ZEND_END_ARG_INFO() +#define arginfo_class_ReflectionProperty_hasDefaultValue arginfo_class_ReflectionProperty_isPromoted #define arginfo_class_ReflectionProperty_getDefaultValue arginfo_class_ReflectionFunctionAbstract___clone @@ -400,6 +402,8 @@ ZEND_END_ARG_INFO() #define arginfo_class_ReflectionParameter_isVariadic arginfo_class_ReflectionFunctionAbstract___clone +#define arginfo_class_ReflectionParameter_isPromoted arginfo_class_ReflectionProperty_isPromoted + #define arginfo_class_ReflectionParameter_getAttributes arginfo_class_ReflectionFunctionAbstract_getAttributes #define arginfo_class_ReflectionType___clone arginfo_class_ReflectionFunctionAbstract___clone @@ -604,6 +608,7 @@ ZEND_METHOD(ReflectionProperty, isPrivate); ZEND_METHOD(ReflectionProperty, isProtected); ZEND_METHOD(ReflectionProperty, isStatic); ZEND_METHOD(ReflectionProperty, isDefault); +ZEND_METHOD(ReflectionProperty, isPromoted); ZEND_METHOD(ReflectionProperty, getModifiers); ZEND_METHOD(ReflectionProperty, getDeclaringClass); ZEND_METHOD(ReflectionProperty, getDocComment); @@ -644,6 +649,7 @@ ZEND_METHOD(ReflectionParameter, getDefaultValue); ZEND_METHOD(ReflectionParameter, isDefaultValueConstant); ZEND_METHOD(ReflectionParameter, getDefaultValueConstantName); ZEND_METHOD(ReflectionParameter, isVariadic); +ZEND_METHOD(ReflectionParameter, isPromoted); ZEND_METHOD(ReflectionParameter, getAttributes); ZEND_METHOD(ReflectionType, allowsNull); ZEND_METHOD(ReflectionType, __toString); @@ -851,6 +857,7 @@ static const zend_function_entry class_ReflectionProperty_methods[] = { ZEND_ME(ReflectionProperty, isProtected, arginfo_class_ReflectionProperty_isProtected, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionProperty, isStatic, arginfo_class_ReflectionProperty_isStatic, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionProperty, isDefault, arginfo_class_ReflectionProperty_isDefault, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionProperty, isPromoted, arginfo_class_ReflectionProperty_isPromoted, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionProperty, getModifiers, arginfo_class_ReflectionProperty_getModifiers, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionProperty, getDeclaringClass, arginfo_class_ReflectionProperty_getDeclaringClass, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionProperty, getDocComment, arginfo_class_ReflectionProperty_getDocComment, ZEND_ACC_PUBLIC) @@ -903,6 +910,7 @@ static const zend_function_entry class_ReflectionParameter_methods[] = { ZEND_ME(ReflectionParameter, isDefaultValueConstant, arginfo_class_ReflectionParameter_isDefaultValueConstant, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionParameter, getDefaultValueConstantName, arginfo_class_ReflectionParameter_getDefaultValueConstantName, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionParameter, isVariadic, arginfo_class_ReflectionParameter_isVariadic, ZEND_ACC_PUBLIC) + ZEND_ME(ReflectionParameter, isPromoted, arginfo_class_ReflectionParameter_isPromoted, ZEND_ACC_PUBLIC) ZEND_ME(ReflectionParameter, getAttributes, arginfo_class_ReflectionParameter_getAttributes, ZEND_ACC_PUBLIC) ZEND_FE_END }; diff --git a/ext/reflection/tests/bug71767.phpt b/ext/reflection/tests/bug71767.phpt index c20073c67a..95094290bf 100644 --- a/ext/reflection/tests/bug71767.phpt +++ b/ext/reflection/tests/bug71767.phpt @@ -27,13 +27,21 @@ $func = function( ) { }; +/** Correct docblock */ +$func2 = fn( + /** wrong docblock */ + $arg +) => null; + $reflectionFunction = new ReflectionFunction('foo'); $reflectionClass = new ReflectionClass(Foo::class); $reflectionClosure = new ReflectionFunction($func); +$reflectionArrowFn = new ReflectionFunction($func2); echo $reflectionFunction->getDocComment() . PHP_EOL; echo $reflectionClass->getMethod('bar')->getDocComment() . PHP_EOL; echo $reflectionClosure->getDocComment() . PHP_EOL; +echo $reflectionArrowFn->getDocComment() . PHP_EOL; echo "Done\n"; ?> @@ -41,4 +49,5 @@ echo "Done\n"; /** Correct docblock */ /** Correct docblock */ /** Correct docblock */ +/** Correct docblock */ Done diff --git a/ext/reflection/tests/constructor_promotion.phpt b/ext/reflection/tests/constructor_promotion.phpt new file mode 100644 index 0000000000..d0a09aaee0 --- /dev/null +++ b/ext/reflection/tests/constructor_promotion.phpt @@ -0,0 +1,70 @@ +--TEST-- +Using Reflection on promoted properties +--FILE-- +<?php + +class Test { + public $z; + public function __construct( + public int $x, + /** @SomeAnnotation() */ + public string $y = "123", + string $z = "abc", + ) {} +} + +$rc = new ReflectionClass(Test::class); +echo $rc, "\n"; + +$y = $rc->getProperty('y'); +var_dump($y->isPromoted()); +var_dump($y->getDocComment()); +$z = $rc->getProperty('z'); +var_dump($z->isPromoted()); + +echo "\n"; + +$rp = new ReflectionParameter([Test::class, '__construct'], 'y'); +var_dump($rp->isPromoted()); +$rp = new ReflectionParameter([Test::class, '__construct'], 'z'); +var_dump($rp->isPromoted()); + +?> +--EXPECTF-- +Class [ <user> class Test ] { + @@ %s 3-11 + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [3] { + Property [ public $z = NULL ] + Property [ public int $x ] + Property [ public string $y ] + } + + - Methods [1] { + Method [ <user, ctor> public method __construct ] { + @@ %s 5 - 10 + + - Parameters [3] { + Parameter #0 [ <required> int $x ] + Parameter #1 [ <optional> string $y = '123' ] + Parameter #2 [ <optional> string $z = 'abc' ] + } + } + } +} + +bool(true) +string(24) "/** @SomeAnnotation() */" +bool(false) + +bool(true) +bool(false) |