@@ -4838,6 +4838,25 @@ class InitializerExprTypeResolver
48384838 return getClassConstFetchTypeByReflection (class_, constantName, classReflection.raw (), getTypeCallback);
48394839 }
48404840
4841+ /* getEnumCaseValueType(): the case value resolved under the
4842+ * currentlyResolvingClassConstant guard, mixed on re-entry */
4843+ zv::Val getEnumCaseValueType (zend_string *className, zend_string *caseName, zval *valueExpr, zval *context) const
4844+ {
4845+ zend_string *resolvingName = zend_string_concat3 (ZSTR_VAL (className), ZSTR_LEN (className), " ::" , 2 , ZSTR_VAL (caseName), ZSTR_LEN (caseName));
4846+ zv::Val resolvingNameHold = zv::Val::adoptString (resolvingName);
4847+ if (zend_symtable_exists (Z_ARRVAL_P (prop (slots::currentlyResolvingClassConstant)), resolvingName)) {
4848+ return newMixedType ();
4849+ }
4850+
4851+ zval trueValue = {};
4852+ ZVAL_TRUE (&trueValue);
4853+ writeArrayProperty (slots::currentlyResolvingClassConstant, resolvingName, &trueValue);
4854+ zv::Val type = getType (valueExpr, context);
4855+ /* the twin's finally: released with an exception pending too */
4856+ unsetArrayProperty (slots::currentlyResolvingClassConstant, resolvingName);
4857+ return type;
4858+ }
4859+
48414860 /* }}} */
48424861
48434862private:
@@ -5336,6 +5355,19 @@ zv::Val pt_initializer_expr_type_resolver_get_type(zval *resolver, zval *expr, z
53365355 return callResolverMethod (site, resolver, PT_LC (" gettype" ), 2 , argv);
53375356}
53385357
5358+ zv::Val pt_initializer_expr_type_resolver_get_enum_case_value_type (zval *resolver, zend_string *className, zend_string *caseName, zval *valueExpr, zval *context)
5359+ {
5360+ if (EXPECTED (isNativeResolver (resolver) && Z_TYPE_P (valueExpr) == IS_OBJECT )) {
5361+ return InitializerExprTypeResolver (Z_OBJ_P (resolver)).getEnumCaseValueType (className, caseName, valueExpr, context);
5362+ }
5363+ static pt_method_site site;
5364+ zval classNameZv, caseNameZv;
5365+ ZVAL_STR (&classNameZv, className);
5366+ ZVAL_STR (&caseNameZv, caseName);
5367+ zv::Args argv{&classNameZv, &caseNameZv, valueExpr, context};
5368+ return callResolverMethod (site, resolver, PT_LC (" getenumcasevaluetype" ), 4 , argv);
5369+ }
5370+
53395371zv::Val pt_initializer_expr_type_resolver_get_binary_op_type (zval *resolver, pt_ietr_binary_operator op, zval *left, zval *right, const pt_ietr_get_type &getTypeCallback)
53405372{
53415373 if (EXPECTED (isNativeResolver (resolver))) {
@@ -5641,6 +5673,14 @@ PT_MINIT_REGISTRATION(pt_register_initializer_expr_type_resolver)
56415673 PT_RETURN_VAL (IETR_THIS .getType (expr, context));
56425674 });
56435675
5676+ cls.method (sigs::getEnumCaseValueType, [](INTERNAL_FUNCTION_PARAMETERS ) {
5677+ zend_string *className, *caseName;
5678+ zval *valueExpr, *context;
5679+ if (!zp::parse<zp::Str, zp::Str, zp::Obj, zp::Obj>(execute_data, className, caseName, valueExpr, context)) RETURN_THROWS ();
5680+ if (UNEXPECTED (!ietrArgExpr (valueExpr, 3 ) || !ietrArgContext (context, 4 ))) RETURN_THROWS ();
5681+ PT_RETURN_VAL (IETR_THIS .getEnumCaseValueType (className, caseName, valueExpr, context));
5682+ });
5683+
56445684 cls.method (sigs::getConcatType, IETR_OPERATOR_GLUE (self.getConcatType (left, right, getTypeCallback)));
56455685
56465686 cls.method (sigs::resolveConcatType, [](INTERNAL_FUNCTION_PARAMETERS ) {
0 commit comments