Skip to content
Merged
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
27 changes: 27 additions & 0 deletions Zend/tests/varSyntax/class_constant_static_deref.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
--TEST--
Class constants can be used as a class name
--FILE--
<?php

class Test {
const NAME = 'Test2';
}

class Test2 {
const FOO = 42;
public static $foo = 42;

public static function foo() {
return 42;
}
}

var_dump(Test::NAME::FOO);
var_dump(Test::NAME::$foo);
var_dump(Test::NAME::foo());

?>
--EXPECT--
int(42)
int(42)
int(42)
24 changes: 24 additions & 0 deletions Zend/tests/varSyntax/constant_object_deref.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
--TEST--
Constants can be dereferenced as objects (even though they can't be objects)
--FILE--
<?php

const FOO = "foo";
class Bar { const FOO = "foo"; }

try {
FOO->length();
} catch (Error $e) {
echo $e->getMessage(), "\n";
}

try {
Bar::FOO->length();
} catch (Error $e) {
echo $e->getMessage(), "\n";
}

?>
--EXPECT--
Call to a member function length() on string
Call to a member function length() on string
29 changes: 29 additions & 0 deletions Zend/tests/varSyntax/encapsed_string_deref.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
--TEST--
Dereferencing operations on an encapsed string
--FILE--
<?php

$bar = "bar";
var_dump("foo$bar"[0]);
var_dump("foo$bar"->prop);
try {
var_dump("foo$bar"->method());
} catch (Error $e) {
echo $e->getMessage(), "\n";
}

class FooBar { public static $prop = 42; }
var_dump("foo$bar"::$prop);

function foobar() { return 42; }
var_dump("foo$bar"());

?>
--EXPECTF--
string(1) "f"

Warning: Trying to get property 'prop' of non-object in %s on line %d
NULL
Call to a member function method() on string
int(42)
int(42)
24 changes: 24 additions & 0 deletions Zend/tests/varSyntax/magic_const_deref.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
--TEST--
Dereferencing of magic constants
--FILE--
<?php

function test() {
var_dump(__FUNCTION__[0]);
var_dump(__FUNCTION__->prop);
try {
__FUNCTION__->method();
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
}

test();

?>
--EXPECTF--
string(1) "t"

Warning: Trying to get property 'prop' of non-object in %s on line %d
NULL
Call to a member function method() on string
18 changes: 18 additions & 0 deletions Zend/tests/varSyntax/new_instanceof_expr.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
--TEST--
new with an arbitrary expression
--FILE--
<?php

$class = 'class';
var_dump(new ('std'.$class));
var_dump(new ('std'.$class)());
$obj = new stdClass;
var_dump($obj instanceof ('std'.$class));

?>
--EXPECT--
object(stdClass)#1 (0) {
}
object(stdClass)#1 (0) {
}
bool(true)
48 changes: 29 additions & 19 deletions Zend/zend_language_parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,8 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
%type <ast> new_expr anonymous_class class_name class_name_reference simple_variable
%type <ast> internal_functions_in_yacc
%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> variable_class_name dereferencable_scalar constant class_constant
%type <ast> fully_dereferencable array_object_dereferencable
%type <ast> callable_expr callable_variable static_member new_variable
%type <ast> encaps_var encaps_var_offset isset_variables
%type <ast> top_statement_list use_declarations const_list inner_statement_list if_stmt
Expand Down Expand Up @@ -1077,6 +1078,7 @@ class_name:
class_name_reference:
class_name { $$ = $1; }
| new_variable { $$ = $1; }
| '(' expr ')' { $$ = $2; }
;

exit_expr:
Expand All @@ -1102,11 +1104,23 @@ dereferencable_scalar:
T_ARRAY '(' array_pair_list ')' { $$ = $3; $$->attr = ZEND_ARRAY_SYNTAX_LONG; }
| '[' array_pair_list ']' { $$ = $2; $$->attr = ZEND_ARRAY_SYNTAX_SHORT; }
| T_CONSTANT_ENCAPSED_STRING { $$ = $1; }
| '"' encaps_list '"' { $$ = $2; }
;

scalar:
T_LNUMBER { $$ = $1; }
| T_DNUMBER { $$ = $1; }
| T_START_HEREDOC T_ENCAPSED_AND_WHITESPACE T_END_HEREDOC { $$ = $2; }
| T_START_HEREDOC T_END_HEREDOC
{ $$ = zend_ast_create_zval_from_str(ZSTR_EMPTY_ALLOC()); }
| T_START_HEREDOC encaps_list T_END_HEREDOC { $$ = $2; }
| dereferencable_scalar { $$ = $1; }
| constant { $$ = $1; }
| class_constant { $$ = $1; }
;

constant:
name { $$ = zend_ast_create(ZEND_AST_CONST, $1); }
| T_LINE { $$ = zend_ast_create_ex(ZEND_AST_MAGIC_CONST, T_LINE); }
| T_FILE { $$ = zend_ast_create_ex(ZEND_AST_MAGIC_CONST, T_FILE); }
| T_DIR { $$ = zend_ast_create_ex(ZEND_AST_MAGIC_CONST, T_DIR); }
Expand All @@ -1115,18 +1129,10 @@ scalar:
| T_FUNC_C { $$ = zend_ast_create_ex(ZEND_AST_MAGIC_CONST, T_FUNC_C); }
| T_NS_C { $$ = zend_ast_create_ex(ZEND_AST_MAGIC_CONST, T_NS_C); }
| T_CLASS_C { $$ = zend_ast_create_ex(ZEND_AST_MAGIC_CONST, T_CLASS_C); }
| T_START_HEREDOC T_ENCAPSED_AND_WHITESPACE T_END_HEREDOC { $$ = $2; }
| T_START_HEREDOC T_END_HEREDOC
{ $$ = zend_ast_create_zval_from_str(ZSTR_EMPTY_ALLOC()); }
| '"' encaps_list '"' { $$ = $2; }
| T_START_HEREDOC encaps_list T_END_HEREDOC { $$ = $2; }
| dereferencable_scalar { $$ = $1; }
| constant { $$ = $1; }
;

constant:
name { $$ = zend_ast_create(ZEND_AST_CONST, $1); }
| class_name T_PAAMAYIM_NEKUDOTAYIM identifier
class_constant:
class_name T_PAAMAYIM_NEKUDOTAYIM identifier
{ $$ = zend_ast_create_class_const_or_name($1, $3); }
| variable_class_name T_PAAMAYIM_NEKUDOTAYIM identifier
{ $$ = zend_ast_create_class_const_or_name($1, $3); }
Expand All @@ -1138,13 +1144,19 @@ optional_expr:
;

variable_class_name:
dereferencable { $$ = $1; }
fully_dereferencable { $$ = $1; }
;

dereferencable:
fully_dereferencable:
variable { $$ = $1; }
| '(' expr ')' { $$ = $2; }
| dereferencable_scalar { $$ = $1; }
| class_constant { $$ = $1; }
;

array_object_dereferencable:
fully_dereferencable { $$ = $1; }
| constant { $$ = $1; }
;

callable_expr:
Expand All @@ -1156,13 +1168,11 @@ callable_expr:
callable_variable:
simple_variable
{ $$ = zend_ast_create(ZEND_AST_VAR, $1); }
| dereferencable '[' optional_expr ']'
{ $$ = zend_ast_create(ZEND_AST_DIM, $1, $3); }
| constant '[' optional_expr ']'
| array_object_dereferencable '[' optional_expr ']'
{ $$ = zend_ast_create(ZEND_AST_DIM, $1, $3); }
| dereferencable '{' expr '}'
| array_object_dereferencable '{' expr '}'
{ $$ = zend_ast_create_ex(ZEND_AST_DIM, ZEND_DIM_ALTERNATIVE_SYNTAX, $1, $3); }
| dereferencable T_OBJECT_OPERATOR property_name argument_list
| array_object_dereferencable T_OBJECT_OPERATOR property_name argument_list
{ $$ = zend_ast_create(ZEND_AST_METHOD_CALL, $1, $3, $4); }
| function_call { $$ = $1; }
;
Expand All @@ -1172,7 +1182,7 @@ variable:
{ $$ = $1; }
| static_member
{ $$ = $1; }
| dereferencable T_OBJECT_OPERATOR property_name
| array_object_dereferencable T_OBJECT_OPERATOR property_name
{ $$ = zend_ast_create(ZEND_AST_PROP, $1, $3); }
;

Expand Down