-
Notifications
You must be signed in to change notification settings - Fork 7.9k
feat: single expression functions #17677
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
base: master
Are you sure you want to change the base?
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
--TEST-- | ||
Short function declaration | ||
--FILE-- | ||
<?php | ||
function foo(): void = echo 123; | ||
var_dump(foo()); // NULL | ||
|
||
function bar(): int = return 456; | ||
echo bar() . PHP_EOL; | ||
|
||
// function buz(): int = 456; // TODO: must be the same as return 456; | ||
// echo buz() . PHP_EOL; | ||
|
||
function compare(int $what, int $with): string = switch(true) { | ||
case $what > $with: | ||
return "greater"; | ||
break; | ||
case $what < $with: | ||
return "less"; | ||
break; | ||
case $what == $with: | ||
return "equals"; | ||
break; | ||
default: | ||
throw new Exception("Unreachable statement"); | ||
} | ||
var_dump(compare(1, 2)); | ||
var_dump(compare(20, 10)); | ||
var_dump(compare(5, 5)); | ||
|
||
echo "done"; | ||
?> | ||
--EXPECT-- | ||
123NULL | ||
456 | ||
string(4) "less" | ||
string(7) "greater" | ||
string(6) "equals" | ||
done |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
--TEST-- | ||
Short method function declaration | ||
--FILE-- | ||
<?php | ||
class Decorator { | ||
public $proxy; | ||
function getId() = $this->proxy->id; | ||
function getName() = $this->proxy->name; | ||
|
||
function setId($value) = $this->proxy->id = $value; | ||
function setName($value) = $this->proxy->name = $value; | ||
} | ||
|
||
$decorated = new stdClass; | ||
$decorated->id = null; | ||
$decorated->name = null; | ||
|
||
$decorator = new Decorator; | ||
$decorator->proxy = $decorated; | ||
|
||
var_dump($decorated); | ||
|
||
$decorator->setId(1); | ||
$decorator->setName('Dmitrii'); | ||
|
||
var_dump($decorated); | ||
?> | ||
--EXPECT-- | ||
object(stdClass)#1 (2) { | ||
["id"]=> | ||
NULL | ||
["name"]=> | ||
NULL | ||
} | ||
object(stdClass)#1 (2) { | ||
["id"]=> | ||
int(1) | ||
["name"]=> | ||
string(7) "Dmitrii" | ||
} |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Request: Give this file a better name than "2" to say what it's testing that is different from the other file, and update the test description accordingly. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
--TEST-- | ||
Short method function declaration | ||
--FILE-- | ||
<?php | ||
class Describer { | ||
function getType(): string = $this->type; | ||
function getTypeName(): string = match($type) { | ||
"variable" => "Variable", | ||
"function_return" => "Function Return Type", | ||
default => "unknown" | ||
}; | ||
} | ||
?> | ||
--EXPECT-- |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -248,7 +248,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); | |
/* Token used to force a parse error from the lexer */ | ||
%token T_ERROR | ||
|
||
%type <ast> top_statement namespace_name name statement function_declaration_statement | ||
%type <ast> top_statement namespace_name name statement function_declaration_statement function_body | ||
%type <ast> class_declaration_statement 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 | ||
|
@@ -578,9 +578,14 @@ function_name: | |
|
||
function_declaration_statement: | ||
function returns_ref function_name backup_doc_comment '(' parameter_list ')' return_type | ||
backup_fn_flags '{' inner_statement_list '}' backup_fn_flags | ||
{ $$ = zend_ast_create_decl(ZEND_AST_FUNC_DECL, $2 | $13, $1, $4, | ||
zend_ast_get_str($3), $6, NULL, $11, $8, NULL); CG(extra_fn_flags) = $9; } | ||
backup_fn_flags function_body backup_fn_flags | ||
{ $$ = zend_ast_create_decl(ZEND_AST_FUNC_DECL, $2 | $11, $1, $4, | ||
zend_ast_get_str($3), $6, NULL, $10, $8, NULL); CG(extra_fn_flags) = $9; } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This does not look correct. |
||
; | ||
|
||
function_body: | ||
'{' inner_statement_list '}' { $$ = $2; } | ||
| '=' statement { $$ = $2; } | ||
; | ||
|
||
is_reference: | ||
|
@@ -1030,6 +1035,7 @@ absolute_trait_method_reference: | |
method_body: | ||
';' /* abstract method */ { $$ = NULL; } | ||
| '{' inner_statement_list '}' { $$ = $2; } | ||
| '=' statement { $$ = $2; } | ||
; | ||
|
||
property_modifiers: | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm actually kind of shocked that a switch works here, since I thought it was all statements. I would expect
match()
to be much more commonly used here.Checking
switch()
is fine, but please include amatch()
test as well, as that seems the more common use case.Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't really work. If this were a match, the value would fail to be returned, and we'd just return
null
. This only works because of the explicitreturn
statements in the switch.