Skip to content

Commit 6cf2597

Browse files
committed
Treat namespaced names as single token
1 parent f60cf0c commit 6cf2597

17 files changed

+128
-41
lines changed

Zend/tests/attributes/019_variable_attribute_name.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ class A {}
88

99
?>
1010
--EXPECTF--
11-
Parse error: syntax error, unexpected variable "$x", expecting identifier or "static" or "namespace" or "\" in %s on line %d
11+
Parse error: syntax error, unexpected variable "$x" in %s on line %d

Zend/tests/bug43343.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ $foo = 'bar';
88
var_dump(new namespace::$foo);
99
?>
1010
--EXPECTF--
11-
Parse error: %s error%sexpecting%s"\"%sin %sbug43343.php on line 5
11+
Parse error: syntax error, unexpected token "namespace" in %s on line %d

Zend/tests/bug55086.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ namespace N2 {
2626
echo $a->hello(), PHP_EOL;
2727
echo $a->foo(), PHP_EOL;
2828
try {
29-
} catch(namespace \Foo $e)
29+
} catch (namespace\Foo $e)
3030
{
3131
}
3232
}

Zend/tests/grammar/regression_010.phpt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@ Test to check regressions on T_IMPLEMENTS followed by a T_NS_SEPARATOR
55

66
interface A{}
77

8+
// No longer considered legal in PHP 8.
89
class B implements\A {}
910

1011
echo "Done", PHP_EOL;
11-
--EXPECT--
12-
Done
12+
13+
?>
14+
--EXPECTF--
15+
Parse error: syntax error, unexpected namespaced name "implements\A", expecting "{" in %s on line %d
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
--TEST--
2+
Cannot use "namespace" as namespace name, due to conflict with ns-relative names
3+
--FILE--
4+
<?php
5+
6+
namespace NAMEspace;
7+
8+
?>
9+
--EXPECTF--
10+
Fatal error: Cannot use 'NAMEspace' as namespace name in %s on line %d
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
--TEST--
2+
Cannot use "namespace\xyz" as namespace name, due to conflict with ns-relative names
3+
--FILE--
4+
<?php
5+
6+
namespace NAMEspace\xyz;
7+
8+
?>
9+
--EXPECTF--
10+
Parse error: syntax error, unexpected namespace-relative name "NAMEspace\xyz", expecting "{" in %s on line %d
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
--TEST--
2+
Reserved keywords in namespace name
3+
--FILE--
4+
<?php
5+
6+
namespace iter\fn {
7+
function test() {
8+
echo __FUNCTION__, "\n";
9+
}
10+
}
11+
12+
namespace fn {
13+
function test() {
14+
echo __FUNCTION__, "\n";
15+
}
16+
}
17+
18+
namespace self {
19+
function test() {
20+
echo __FUNCTION__, "\n";
21+
}
22+
}
23+
24+
namespace {
25+
use iter\fn;
26+
use function fn\test as test2;
27+
use function self\test as test3;
28+
fn\test();
29+
test2();
30+
test3();
31+
}
32+
33+
?>
34+
--EXPECT--
35+
iter\fn\test
36+
fn\test
37+
self\test
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
--TEST--
2+
Whitespace between namespace separators is no longer allowed
3+
--FILE--
4+
<?php
5+
6+
Foo \ Bar \ Baz;
7+
8+
?>
9+
--EXPECTF--
10+
Parse error: syntax error, unexpected token "\" in %s on line %d

Zend/tests/ns_096.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ use Foo\Bar\{\Baz};
77

88
?>
99
--EXPECTF--
10-
Parse error: syntax error, unexpected token "\", expecting identifier or "function" or "const" in %s on line %d
10+
Parse error: syntax error, unexpected fully qualified name "\Baz", expecting identifier or namespaced name or "function" or "const" in %s on line %d

Zend/tests/ns_trailing_comma_error_01.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ Group use declarations mustn't be empty
55
use Baz\{};
66
?>
77
--EXPECTF--
8-
Parse error: syntax error, unexpected token "}", expecting identifier or "function" or "const" in %s on line %d
8+
Parse error: syntax error, unexpected token "}", expecting identifier or namespaced name or "function" or "const" in %s on line %d

Zend/tests/ns_trailing_comma_error_02.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ Group use declarations mustn't contain just a comma
55
use Baz\{,};
66
?>
77
--EXPECTF--
8-
Parse error: syntax error, unexpected token ",", expecting identifier or "function" or "const" in %s on line %d
8+
Parse error: syntax error, unexpected token ",", expecting identifier or namespaced name or "function" or "const" in %s on line %d

Zend/tests/ns_trailing_comma_error_04.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ Group use declarations mustn't begin with a comma
55
use Baz\{,Foo};
66
?>
77
--EXPECTF--
8-
Parse error: syntax error, unexpected token ",", expecting identifier or "function" or "const" in %s on line %d
8+
Parse error: syntax error, unexpected token ",", expecting identifier or namespaced name or "function" or "const" in %s on line %d

Zend/tests/ns_trailing_comma_error_07.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ Unmixed group use declarations mustn't begin with a comma
55
use function Baz\{,Foo};
66
?>
77
--EXPECTF--
8-
Parse error: syntax error, unexpected token ",", expecting identifier in %s on line %d
8+
Parse error: syntax error, unexpected token ",", expecting identifier or namespaced name in %s on line %d

Zend/tests/special_name_error1.phpt

Lines changed: 0 additions & 10 deletions
This file was deleted.

Zend/zend_compile.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7521,7 +7521,7 @@ void zend_compile_namespace(zend_ast *ast) /* {{{ */
75217521
if (name_ast) {
75227522
name = zend_ast_get_str(name_ast);
75237523

7524-
if (ZEND_FETCH_CLASS_DEFAULT != zend_get_class_fetch_type(name)) {
7524+
if (zend_string_equals_literal_ci(name, "namespace")) {
75257525
zend_error_noreturn(E_COMPILE_ERROR, "Cannot use '%s' as namespace name", ZSTR_VAL(name));
75267526
}
75277527

Zend/zend_language_parser.y

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
8989
%token <ast> T_LNUMBER "integer"
9090
%token <ast> T_DNUMBER "floating-point number"
9191
%token <ast> T_STRING "identifier"
92+
%token <ast> T_NAME_FULLY_QUALIFIED "fully qualified name"
93+
%token <ast> T_NAME_RELATIVE "namespace-relative name"
94+
%token <ast> T_NAME_QUALIFIED "namespaced name"
9295
%token <ast> T_VARIABLE "variable"
9396
%token <ast> T_INLINE_HTML
9497
%token <ast> T_ENCAPSED_AND_WHITESPACE "string content"
@@ -231,7 +234,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
231234
%token T_ERROR
232235

233236
%type <ast> top_statement namespace_name name statement function_declaration_statement
234-
%type <ast> class_declaration_statement trait_declaration_statement
237+
%type <ast> class_declaration_statement trait_declaration_statement legacy_namespace_name
235238
%type <ast> interface_declaration_statement interface_extends_list
236239
%type <ast> group_use_declaration inline_use_declarations inline_use_declaration
237240
%type <ast> mixed_group_use_declaration use_declaration unprefixed_use_declaration
@@ -261,7 +264,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
261264
%type <ast> identifier type_expr_without_static union_type_without_static
262265
%type <ast> inline_function union_type
263266
%type <ast> attributed_statement attributed_class_statement attributed_parameter
264-
%type <ast> attribute_decl attribute attributes
267+
%type <ast> attribute_decl attribute attributes namespace_declaration_name
265268
%type <ast> match match_arm_list non_empty_match_arm_list match_arm match_arm_cond_list
266269

267270
%type <num> returns_ref function fn is_reference is_variadic variable_modifiers
@@ -308,15 +311,29 @@ top_statement_list:
308311
| %empty { $$ = zend_ast_create_list(0, ZEND_AST_STMT_LIST); }
309312
;
310313

314+
/* Name usable in a namespace declaration. */
315+
namespace_declaration_name:
316+
identifier { $$ = $1; }
317+
| T_NAME_QUALIFIED { $$ = $1; }
318+
;
319+
320+
/* Name usable in "use" declarations (loading separator forbidden). */
311321
namespace_name:
312322
T_STRING { $$ = $1; }
313-
| namespace_name T_NS_SEPARATOR T_STRING { $$ = zend_ast_append_str($1, $3); }
323+
| T_NAME_QUALIFIED { $$ = $1; }
324+
;
325+
326+
/* Name usable in "use" declarations (leading separator allowed). */
327+
legacy_namespace_name:
328+
namespace_name { $$ = $1; }
329+
| T_NAME_FULLY_QUALIFIED { $$ = $1; }
314330
;
315331

316332
name:
317-
namespace_name { $$ = $1; $$->attr = ZEND_NAME_NOT_FQ; }
318-
| T_NAMESPACE T_NS_SEPARATOR namespace_name { $$ = $3; $$->attr = ZEND_NAME_RELATIVE; }
319-
| T_NS_SEPARATOR namespace_name { $$ = $2; $$->attr = ZEND_NAME_FQ; }
333+
T_STRING { $$ = $1; $$->attr = ZEND_NAME_NOT_FQ; }
334+
| T_NAME_QUALIFIED { $$ = $1; $$->attr = ZEND_NAME_NOT_FQ; }
335+
| T_NAME_FULLY_QUALIFIED { $$ = $1; $$->attr = ZEND_NAME_FQ; }
336+
| T_NAME_RELATIVE { $$ = $1; $$->attr = ZEND_NAME_RELATIVE; }
320337
;
321338

322339
attribute_decl:
@@ -350,10 +367,10 @@ top_statement:
350367
{ $$ = zend_ast_create(ZEND_AST_HALT_COMPILER,
351368
zend_ast_create_zval_from_long(zend_get_scanned_file_offset()));
352369
zend_stop_lexing(); }
353-
| T_NAMESPACE namespace_name ';'
370+
| T_NAMESPACE namespace_declaration_name ';'
354371
{ $$ = zend_ast_create(ZEND_AST_NAMESPACE, $2, NULL);
355372
RESET_DOC_COMMENT(); }
356-
| T_NAMESPACE namespace_name { RESET_DOC_COMMENT(); }
373+
| T_NAMESPACE namespace_declaration_name { RESET_DOC_COMMENT(); }
357374
'{' top_statement_list '}'
358375
{ $$ = zend_ast_create(ZEND_AST_NAMESPACE, $2, $5); }
359376
| T_NAMESPACE { RESET_DOC_COMMENT(); }
@@ -372,17 +389,13 @@ use_type:
372389
;
373390

374391
group_use_declaration:
375-
namespace_name T_NS_SEPARATOR '{' unprefixed_use_declarations possible_comma '}'
392+
legacy_namespace_name T_NS_SEPARATOR '{' unprefixed_use_declarations possible_comma '}'
376393
{ $$ = zend_ast_create(ZEND_AST_GROUP_USE, $1, $4); }
377-
| T_NS_SEPARATOR namespace_name T_NS_SEPARATOR '{' unprefixed_use_declarations possible_comma '}'
378-
{ $$ = zend_ast_create(ZEND_AST_GROUP_USE, $2, $5); }
379394
;
380395

381396
mixed_group_use_declaration:
382-
namespace_name T_NS_SEPARATOR '{' inline_use_declarations possible_comma '}'
397+
legacy_namespace_name T_NS_SEPARATOR '{' inline_use_declarations possible_comma '}'
383398
{ $$ = zend_ast_create(ZEND_AST_GROUP_USE, $1, $4);}
384-
| T_NS_SEPARATOR namespace_name T_NS_SEPARATOR '{' inline_use_declarations possible_comma '}'
385-
{ $$ = zend_ast_create(ZEND_AST_GROUP_USE, $2, $5); }
386399
;
387400

388401
possible_comma:
@@ -424,8 +437,10 @@ unprefixed_use_declaration:
424437
;
425438

426439
use_declaration:
427-
unprefixed_use_declaration { $$ = $1; }
428-
| T_NS_SEPARATOR unprefixed_use_declaration { $$ = $2; }
440+
legacy_namespace_name
441+
{ $$ = zend_ast_create(ZEND_AST_USE_ELEM, $1, NULL); }
442+
| legacy_namespace_name T_AS T_STRING
443+
{ $$ = zend_ast_create(ZEND_AST_USE_ELEM, $1, $3); }
429444
;
430445

431446
const_list:

Zend/zend_language_scanner.l

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1596,10 +1596,6 @@ NEWLINE ("\r"|"\n"|"\r\n")
15961596
RETURN_TOKEN(T_PAAMAYIM_NEKUDOTAYIM);
15971597
}
15981598

1599-
<ST_IN_SCRIPTING>"\\" {
1600-
RETURN_TOKEN(T_NS_SEPARATOR);
1601-
}
1602-
16031599
<ST_IN_SCRIPTING>"..." {
16041600
RETURN_TOKEN(T_ELLIPSIS);
16051601
}
@@ -2288,6 +2284,22 @@ inline_char_handler:
22882284
RETURN_TOKEN_WITH_VAL(T_ENCAPSED_AND_WHITESPACE);
22892285
}
22902286
2287+
<ST_IN_SCRIPTING>"namespace"("\\"{LABEL})+ {
2288+
RETURN_TOKEN_WITH_STR(T_NAME_RELATIVE, sizeof("namespace\\") - 1);
2289+
}
2290+
2291+
<ST_IN_SCRIPTING>{LABEL}("\\"{LABEL})+ {
2292+
RETURN_TOKEN_WITH_STR(T_NAME_QUALIFIED, 0);
2293+
}
2294+
2295+
<ST_IN_SCRIPTING>"\\"{LABEL}("\\"{LABEL})* {
2296+
RETURN_TOKEN_WITH_STR(T_NAME_FULLY_QUALIFIED, 1);
2297+
}
2298+
2299+
<ST_IN_SCRIPTING>"\\" {
2300+
RETURN_TOKEN(T_NS_SEPARATOR);
2301+
}
2302+
22912303
<ST_IN_SCRIPTING,ST_VAR_OFFSET>{LABEL} {
22922304
RETURN_TOKEN_WITH_STR(T_STRING, 0);
22932305
}

0 commit comments

Comments
 (0)