Skip to content
Open
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
1 change: 1 addition & 0 deletions Zend/tests/class_name_as_scalar.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
class name as scalar from ::class keyword
--FILE--
<?php
// Keep in sync with fn_callbacks/class_name_resolution.phpt

namespace Foo\Bar {
class One {
Expand Down
80 changes: 80 additions & 0 deletions Zend/tests/fn_callbacks/basic.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
--TEST--
fn:: callback basic usage
--FILE--
<?php

namespace Foo\Bar {
class One {
function getThisCallback() {
return fn::$this->meth;
}
}
function baz() {
return 'Foo.Bar.baz';
}
function qux() {
return baz();
}

echo "Static\n";
var_dump(fn::One::method); // resolve in namespace
var_dump(fn::\One::mEtHod); // resolve fully qualified

echo "Dynamic\n";
$one = new One();
var_dump(fn::$one->meth);
var_dump($one->getThisCallback());
var_dump($one === $one->getThisCallback()[0]);

echo "Function\n";
var_dump(fn::intval);

// TODO implement name resolution
//var_dump(fn::baz);
}

namespace {
use function Foo\Bar\baz, Foo\Bar\qux;
var_dump(fn::iNtVal);
var_dump(fn::Foo\intval);

// TODO implement name resolution
//var_dump(fn::baz);
//var_dump(fn::qux);
}

?>
--EXPECT--
Static
array(2) {
[0]=>
string(11) "Foo\Bar\One"
[1]=>
string(6) "method"
}
array(2) {
[0]=>
string(3) "One"
[1]=>
string(6) "mEtHod"
}
Dynamic
array(2) {
[0]=>
object(Foo\Bar\One)#1 (0) {
}
[1]=>
string(4) "meth"
}
array(2) {
[0]=>
object(Foo\Bar\One)#1 (0) {
}
[1]=>
string(4) "meth"
}
bool(true)
Function
string(6) "intval"
string(6) "iNtVal"
string(10) "Foo\intval"
54 changes: 54 additions & 0 deletions Zend/tests/fn_callbacks/class_name_resolution.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
--TEST--
fn:: callback with static classname
--FILE--
<?php
// Keep in sync with class_name_as_scalar.phpt

namespace Foo\Bar {
class One {
}
class Two extends One {
public static function run() {
var_dump((fn::self::meth)[0]); // self compile time lookup
var_dump((fn::static::meth)[0]); // runtime lookup
var_dump((fn::parent::meth)[0]); // runtime lookup
var_dump((fn::Baz::meth)[0]); // default compile time lookup
}
}
class Three extends Two {
}
echo "In NS\n";
var_dump((fn::Moo::meth)[0]); // resolve in namespace
}

namespace {
use Bee\Bop as Moo,
Foo\Bar\One;
echo "Top\n";
var_dump((fn::One::meth)[0]); // resolve from use
var_dump((fn::Boo::meth)[0]); // resolve in global namespace
var_dump((fn::Moo::meth)[0]); // resolve from use as
var_dump((fn::\Moo::meth)[0]); // resolve fully qualified
Foo\Bar\Two::run(); // resolve runtime lookups
echo "Parent\n";
Foo\Bar\Three::run(); // resolve runtime lookups with inheritance
}

?>
--EXPECT--
In NS
string(11) "Foo\Bar\Moo"
Top
string(11) "Foo\Bar\One"
string(3) "Boo"
string(7) "Bee\Bop"
string(3) "Moo"
string(11) "Foo\Bar\Two"
string(11) "Foo\Bar\Two"
string(11) "Foo\Bar\One"
string(11) "Foo\Bar\Baz"
Parent
string(11) "Foo\Bar\Two"
string(13) "Foo\Bar\Three"
string(11) "Foo\Bar\One"
string(11) "Foo\Bar\Baz"
39 changes: 39 additions & 0 deletions Zend/zend_language_parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
%type <ast> exit_expr scalar backticks_expr lexical_var function_call member_name property_name
%type <ast> variable_class_name dereferencable_scalar constant dereferencable
%type <ast> callable_expr callable_variable static_member new_variable
%type <ast> callback callback_expr
%type <ast> encaps_var encaps_var_offset isset_variables
%type <ast> top_statement_list use_declarations const_list inner_statement_list if_stmt
%type <ast> alt_if_stmt for_exprs switch_case_list global_var_list static_var_list
Expand Down Expand Up @@ -884,6 +885,8 @@ new_expr:
expr:
variable
{ $$ = $1; }
| callback
{ $$ = $1; }
| T_LIST '(' array_pair_list ')' '=' expr
{ $3->attr = ZEND_ARRAY_SYNTAX_LIST; $$ = zend_ast_create(ZEND_AST_ASSIGN, $3, $6); }
| '[' array_pair_list ']' '=' expr
Expand Down Expand Up @@ -1124,6 +1127,42 @@ scalar:
| constant { $$ = $1; }
;

callback:
T_FN T_PAAMAYIM_NEKUDOTAYIM callback_expr { $$ = $3; }
;

callback_expr:
T_VARIABLE T_OBJECT_OPERATOR T_STRING {
$$ = zend_ast_list_add(
zend_ast_create_list(
1, ZEND_AST_ARRAY,
zend_ast_create(
ZEND_AST_ARRAY_ELEM,
zend_ast_create(ZEND_AST_VAR, $1),
NULL
)
),
zend_ast_create(ZEND_AST_ARRAY_ELEM, $3, NULL)
);
}
| class_name T_PAAMAYIM_NEKUDOTAYIM T_STRING {
$$ = zend_ast_list_add(
zend_ast_create_list(
1, ZEND_AST_ARRAY,
zend_ast_create(
ZEND_AST_ARRAY_ELEM,
zend_ast_create(ZEND_AST_CLASS_NAME, $1),
NULL
)
),
zend_ast_create(ZEND_AST_ARRAY_ELEM, $3, NULL)
);
}
| name {
$$ = $1;
}
;

constant:
name { $$ = zend_ast_create(ZEND_AST_CONST, $1); }
| class_name T_PAAMAYIM_NEKUDOTAYIM identifier
Expand Down