Fix nested namespaced typed property in gen_stub.php (#7418)

Property escape namespaced class name in property types.
This commit is contained in:
Go Kudo 2021-08-31 18:56:39 +09:00 committed by GitHub
parent 52d3af1790
commit eaac77f4e7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 46 additions and 5 deletions

View file

@ -395,6 +395,11 @@ class SimpleType {
return str_replace('\\', '\\\\', $this->name);
}
public function toCVarEscapedName(): string {
$name = str_replace('_', '__', $this->name);
return str_replace('\\', '_', $this->name);
}
public function equals(SimpleType $other): bool {
return $this->name === $other->name && $this->isBuiltin === $other->isBuiltin;
}
@ -1374,7 +1379,9 @@ class PropertyInfo
if (count($arginfoType->classTypes) >= 2) {
foreach ($arginfoType->classTypes as $classType) {
$className = $classType->name;
$code .= "\tzend_string *property_{$propertyName}_class_{$className} = zend_string_init(\"$className\", sizeof(\"$className\") - 1, 1);\n";
$escapedClassName = $classType->toEscapedName();
$varEscapedClassName = $classType->toCVarEscapedName();
$code .= "\tzend_string *property_{$propertyName}_class_{$varEscapedClassName} = zend_string_init(\"{$escapedClassName}\", sizeof(\"{$escapedClassName}\") - 1, 1);\n";
}
$classTypeCount = count($arginfoType->classTypes);
@ -1383,7 +1390,8 @@ class PropertyInfo
foreach ($arginfoType->classTypes as $k => $classType) {
$className = $classType->name;
$code .= "\tproperty_{$propertyName}_type_list->types[$k] = (zend_type) ZEND_TYPE_INIT_CLASS(property_{$propertyName}_class_{$className}, 0, 0);\n";
$escapedClassName = $classType->toEscapedName();
$code .= "\tproperty_{$propertyName}_type_list->types[$k] = (zend_type) ZEND_TYPE_INIT_CLASS(property_{$propertyName}_class_{$escapedClassName}, 0, 0);\n";
}
$typeMaskCode = $this->type->toArginfoType()->toTypeMask();
@ -1392,9 +1400,11 @@ class PropertyInfo
$typeCode = "property_{$propertyName}_type";
} else {
$className = $arginfoType->classTypes[0]->name;
$code .= "\tzend_string *property_{$propertyName}_class_{$className} = zend_string_init(\"$className\", sizeof(\"$className\")-1, 1);\n";
$escapedClassName = $arginfoType->classTypes[0]->toEscapedName();
$varEscapedClassName = $arginfoType->classTypes[0]->toCVarEscapedName();
$code .= "\tzend_string *property_{$propertyName}_class_{$varEscapedClassName} = zend_string_init(\"{$escapedClassName}\", sizeof(\"${escapedClassName}\")-1, 1);\n";
$typeCode = "(zend_type) ZEND_TYPE_INIT_CLASS(property_{$propertyName}_class_{$className}, 0, " . $arginfoType->toTypeMask() . ")";
$typeCode = "(zend_type) ZEND_TYPE_INIT_CLASS(property_{$propertyName}_class_{$varEscapedClassName}, 0, " . $arginfoType->toTypeMask() . ")";
}
} else {
$typeCode = "(zend_type) ZEND_TYPE_INIT_MASK(" . $arginfoType->toTypeMask() . ")";

View file

@ -88,6 +88,8 @@ namespace ZendTestNS {
namespace ZendTestNS2 {
class Foo {
public ZendSubNS\Foo $foo;
public function method(): void {}
}

View file

@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: 93bb8b9120e510e8c3afc29dc0a5d47cb6b5f10e */
* Stub hash: 04d48fa64594bacba57210dcb94381f83951116c */
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_test_array_return, 0, 0, IS_ARRAY, 0)
ZEND_END_ARG_INFO()
@ -296,6 +296,13 @@ static zend_class_entry *register_class_ZendTestNS2_Foo(void)
INIT_NS_CLASS_ENTRY(ce, "ZendTestNS2", "Foo", class_ZendTestNS2_Foo_methods);
class_entry = zend_register_internal_class_ex(&ce, NULL);
zend_string *property_foo_class_ZendTestNS2_ZendSubNS_Foo = zend_string_init("ZendTestNS2\\ZendSubNS\\Foo", sizeof("ZendTestNS2\\ZendSubNS\\Foo")-1, 1);
zval property_foo_default_value;
ZVAL_UNDEF(&property_foo_default_value);
zend_string *property_foo_name = zend_string_init("foo", sizeof("foo") - 1, 1);
zend_declare_typed_property(class_entry, property_foo_name, &property_foo_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_foo_class_ZendTestNS2_ZendSubNS_Foo, 0, 0));
zend_string_release(property_foo_name);
return class_entry;
}

View file

@ -0,0 +1,22 @@
--TEST--
gen_stub.php: nested namespaced typed properties test.
--EXTENSIONS--
zend_test
--FILE--
<?php
$foo = new \ZendTestNS2\Foo();
var_dump($foo);
$foo->foo = new \ZendTestNS2\ZendSubNS\Foo();
var_dump($foo);
?>
--EXPECTF--
object(ZendTestNS2\Foo)#%d (%d) {
["foo"]=>
uninitialized(ZendTestNS2\ZendSubNS\Foo)
}
object(ZendTestNS2\Foo)#%d (%d) {
["foo"]=>
object(ZendTestNS2\ZendSubNS\Foo)#%d (%d) {
}
}