Skip to content

[draft] short constructor #19133

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all 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
14 changes: 14 additions & 0 deletions Zend/tests/ctor/error-ctor-duplicate.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
--TEST--
Disallow duplicate short and full ctors
--FILE--
<?php

class DTO (
public int $number,
) {
public function __construct() {}
}

?>
--EXPECTF--
Fatal error: Cannot redeclare DTO::__construct() in %s on line %d
9 changes: 9 additions & 0 deletions Zend/tests/ctor/no-ctor-simple.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
--TEST--
Class does not contain any statements
--FILE--
<?php

class DTO;

?>
--EXPECTF--
23 changes: 23 additions & 0 deletions Zend/tests/ctor/short-ctor-ast-printer.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
--TEST--
Pass short ctor parameters
--FILE--
<?php

try {
assert(false && function () {
class Empty0 ();
});
} catch (Throwable $e) {
echo $e->getMessage(), PHP_EOL;
}

?>
--EXPECTF--
assert(false && function () {
class Empty0 {
public function __construct() {
}

}

})
27 changes: 27 additions & 0 deletions Zend/tests/ctor/short-ctor-ast-printer2.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
--TEST--
Pass short ctor parameters
--FILE--
<?php

try {
assert(false && function () {

class DTO (
public int $number,
);

});
} catch (Throwable $e) {
echo $e->getMessage(), PHP_EOL;
}

?>
--EXPECTF--
assert(false && function () {
class DTO {
public function __construct(public int $number) {
}

}

})
42 changes: 42 additions & 0 deletions Zend/tests/ctor/short-ctor-ast-printer3.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
--TEST--
Pass short ctor parameters
--FILE--
<?php

try {
assert(false && function () {

abstract class Family($string);

class Child1($string) extends Family () {}
class Child2($string) extends Family (555) {}

});
} catch (Throwable $e) {
echo $e->getMessage(), PHP_EOL;
}

?>
--EXPECTF--
assert(false && function () {
abstract class Family {
public function __construct($string) {
}

}

class Child1 extends Family {
public function __construct($string) {
parent::__construct();
}

}

class Child2 extends Family {
public function __construct($string) {
parent::__construct(555);
}

}

})
35 changes: 35 additions & 0 deletions Zend/tests/ctor/short-ctor-ast-printer4.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
--TEST--
Pass short ctor parameters
--FILE--
<?php

try {
assert(false && function () {

abstract class Family(protected $protected);

class Child1(public $string) extends Family ($string) {}


});
} catch (Throwable $e) {
echo $e->getMessage(), PHP_EOL;
}

?>
--EXPECTF--
assert(false && function () {
abstract class Family {
public function __construct(protected $protected) {
}

}

class Child1 extends Family {
public function __construct(public $string) {
parent::__construct($string);
}

}

})
18 changes: 18 additions & 0 deletions Zend/tests/ctor/short-ctor-const.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
--TEST--
Pass short ctor parameters
--FILE--
<?php

abstract class Family(protected $string);

class Child1($string) extends Family (self::VALUE) {
const VALUE = 123;
}

var_dump(new Child1("test"));
?>
--EXPECTF--
object(Child1)#1 (1) {
["string":protected]=>
int(123)
}
16 changes: 16 additions & 0 deletions Zend/tests/ctor/short-ctor-extends.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
--TEST--
Pass short ctor parameters
--FILE--
<?php

abstract class Family(protected $string);

class Child1($string) extends Family ($string) {}

var_dump(new Child1("test"));
?>
--EXPECTF--
object(Child1)#1 (1) {
["string":protected]=>
string(4) "test"
}
20 changes: 20 additions & 0 deletions Zend/tests/ctor/short-ctor-prop.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
--TEST--
Pass short ctor parameters
--FILE--
<?php

abstract class Family(protected $string);

class Child1($string) extends Family ($this->internal_string) {
private $internal_string = "internal";
}

var_dump(new Child1("test"));
?>
--EXPECTF--
object(Child1)#1 (2) {
["string":protected]=>
string(8) "internal"
["internal_string":"Child1":private]=>
string(8) "internal"
}
28 changes: 28 additions & 0 deletions Zend/tests/ctor/short-ctor-simple.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
--TEST--
Pass short ctor parameters
--FILE--
<?php

class Empty0 ();

var_dump(new Empty0());

class DTO (
public int $number,
);

var_dump(new DTO(50));

class Value (int $number);

var_dump(new Value(50));
?>
--EXPECTF--
object(Empty0)#1 (0) {
}
object(DTO)#1 (1) {
["number"]=>
int(50)
}
object(Value)#1 (0) {
}
2 changes: 1 addition & 1 deletion Zend/tests/grammar/regression_010.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ echo "Done", PHP_EOL;

?>
--EXPECTF--
Parse error: syntax error, unexpected namespaced name "implements\A", expecting "{" in %s on line %d
Parse error: syntax error, unexpected namespaced name "implements\A", expecting ";" or "{" in %s on line %d
51 changes: 42 additions & 9 deletions Zend/zend_language_parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
#define YYMALLOC malloc
#define YYFREE free
#endif
void* temp;
}

%code requires {
Expand Down Expand Up @@ -252,7 +253,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
%token T_ERROR

%type <ast> top_statement namespace_name name statement function_declaration_statement
%type <ast> class_declaration_statement trait_declaration_statement legacy_namespace_name
%type <ast> class_declaration_statement class_body_statement parent_ctr_call class_short_ctor trait_declaration_statement legacy_namespace_name
%type <ast> interface_declaration_statement interface_extends_list
%type <ast> group_use_declaration inline_use_declarations inline_use_declaration
%type <ast> mixed_group_use_declaration use_declaration unprefixed_use_declaration
Expand Down Expand Up @@ -291,7 +292,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);

%type <num> returns_ref function fn is_reference is_variadic property_modifiers property_hook_modifiers
%type <num> method_modifiers class_const_modifiers member_modifier optional_cpp_modifiers
%type <num> class_modifiers class_modifier anonymous_class_modifiers anonymous_class_modifiers_optional use_type backup_fn_flags
%type <num> class_modifiers class_modifiers_optional class_modifier anonymous_class_modifiers anonymous_class_modifiers_optional use_type backup_fn_flags

%type <ptr> backup_lex_pos
%type <str> backup_doc_comment
Expand Down Expand Up @@ -602,12 +603,44 @@ is_variadic:
;

class_declaration_statement:
class_modifiers T_CLASS { $<num>$ = CG(zend_lineno); }
T_STRING extends_from implements_list backup_doc_comment '{' class_statement_list '}'
{ $$ = zend_ast_create_decl(ZEND_AST_CLASS, $1, $<num>3, $7, zend_ast_get_str($4), $5, $6, $9, NULL, NULL); }
| T_CLASS { $<num>$ = CG(zend_lineno); }
T_STRING extends_from implements_list backup_doc_comment '{' class_statement_list '}'
{ $$ = zend_ast_create_decl(ZEND_AST_CLASS, 0, $<num>2, $6, zend_ast_get_str($3), $4, $5, $8, NULL, NULL); }
class_modifiers_optional T_CLASS { $<num>$ = CG(zend_lineno); } T_STRING
class_short_ctor
extends_from implements_list backup_doc_comment class_body_statement
{
zend_ast_decl *ctor = (zend_ast_decl *)$5;
if (ctor && ctor->child[2] && temp) {
ctor->child[2] = zend_ast_list_add(ctor->child[2], temp);
}
zend_ast* stmts = zend_ast_create_list(2, ZEND_AST_STMT_LIST, $5, $9);
$$ = zend_ast_create_decl(ZEND_AST_CLASS, $1, $<num>3, $8, zend_ast_get_str($4), $6, $7, stmts, NULL, NULL); }
;

class_short_ctor:
'(' parameter_list ')'
{ $$ = zend_ast_create_decl(ZEND_AST_METHOD, ZEND_ACC_PUBLIC, CG(zend_lineno), NULL,
ZSTR_KNOWN(ZEND_STR_CTOR), $2, NULL, zend_ast_create_list(0, ZEND_AST_STMT_LIST), NULL, NULL); }
| %empty { $$ = NULL; }
;

class_body_statement:
'{' class_statement_list '}' { $$ = $2; }
| ';' { $$ = NULL; }
;

parent_ctr_call:
argument_list
{
zval zv; ZVAL_INTERNED_STR(&zv, ZSTR_KNOWN(ZEND_STR_PARENT));
$$ = zend_ast_create(ZEND_AST_STATIC_CALL,
zend_ast_create_zval_ex(&zv, ZEND_NAME_NOT_FQ),
zend_ast_create_zval_from_str(ZSTR_KNOWN(ZEND_STR_CTOR)),
$1); }
| %empty { $$ = NULL; }
;

class_modifiers_optional:
%empty { $$ = 0; }
| class_modifiers { $$ = $1; }
;

class_modifiers:
Expand Down Expand Up @@ -669,7 +702,7 @@ enum_case_expr:

extends_from:
%empty { $$ = NULL; }
| T_EXTENDS class_name { $$ = $2; }
| T_EXTENDS class_name parent_ctr_call { $$ = $2; temp = $3; }
;

interface_extends_list:
Expand Down
1 change: 1 addition & 0 deletions Zend/zend_string.h
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,7 @@ EMPTY_SWITCH_DEFAULT_CASE()
_(ZEND_STR_VALUE, "value") \
_(ZEND_STR_KEY, "key") \
_(ZEND_STR_MAGIC_INVOKE, "__invoke") \
_(ZEND_STR_CTOR, "__construct") \
_(ZEND_STR_PREVIOUS, "previous") \
_(ZEND_STR_CODE, "code") \
_(ZEND_STR_MESSAGE, "message") \
Expand Down
Loading