Skip to content

Commit 79eb561

Browse files
committed
Treat namespaced names as single token
1 parent 613a56d commit 79eb561

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 '$x' (T_VARIABLE), expecting identifier (T_STRING) or static (T_STATIC) or namespace (T_NAMESPACE) or \\ (T_NS_SEPARATOR) in %s on line %d
11+
Parse error: syntax error, unexpected '$x' (T_VARIABLE) 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%sT_NS_SEPARATOR%sin %sbug43343.php on line 5
11+
Parse error: syntax error, unexpected 'namespace' (T_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 'implements\A' (T_NAME_QUALIFIED), 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\xyz' (T_NAME_RELATIVE), 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 '\' (T_NS_SEPARATOR) 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 '\' (T_NS_SEPARATOR), expecting identifier (T_STRING) or function (T_FUNCTION) or const (T_CONST) in %s on line 3
10+
Parse error: syntax error, unexpected '\Baz' (T_NAME_FULLY_QUALIFIED), expecting identifier (T_STRING) or namespaced name (T_NAME_QUALIFIED) or function (T_FUNCTION) or const (T_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 '}', expecting identifier (T_STRING) or function (T_FUNCTION) or const (T_CONST) in %s on line %d
8+
Parse error: syntax error, unexpected '}', expecting identifier (T_STRING) or namespaced name (T_NAME_QUALIFIED) or function (T_FUNCTION) or const (T_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 ',', expecting identifier (T_STRING) or function (T_FUNCTION) or const (T_CONST) in %s on line %d
8+
Parse error: syntax error, unexpected ',', expecting identifier (T_STRING) or namespaced name (T_NAME_QUALIFIED) or function (T_FUNCTION) or const (T_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 ',', expecting identifier (T_STRING) or function (T_FUNCTION) or const (T_CONST) in %s on line %d
8+
Parse error: syntax error, unexpected ',', expecting identifier (T_STRING) or namespaced name (T_NAME_QUALIFIED) or function (T_FUNCTION) or const (T_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 ',', expecting identifier (T_STRING) in %s on line %d
8+
Parse error: syntax error, unexpected ',', expecting identifier (T_STRING) or namespaced name (T_NAME_QUALIFIED) 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
@@ -7294,7 +7294,7 @@ void zend_compile_namespace(zend_ast *ast) /* {{{ */
72947294
if (name_ast) {
72957295
name = zend_ast_get_str(name_ast);
72967296

7297-
if (ZEND_FETCH_CLASS_DEFAULT != zend_get_class_fetch_type(name)) {
7297+
if (zend_string_equals_literal_ci(name, "namespace")) {
72987298
zend_error_noreturn(E_COMPILE_ERROR, "Cannot use '%s' as namespace name", ZSTR_VAL(name));
72997299
}
73007300

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 number (T_LNUMBER)"
9090
%token <ast> T_DNUMBER "floating-point number (T_DNUMBER)"
9191
%token <ast> T_STRING "identifier (T_STRING)"
92+
%token <ast> T_NAME_FULLY_QUALIFIED "fully qualified name (T_NAME_FULLY_QUALIFIED)"
93+
%token <ast> T_NAME_RELATIVE "namespace-relative name (T_NAME_RELATIVE)"
94+
%token <ast> T_NAME_QUALIFIED "namespaced name (T_NAME_QUALIFIED)"
9295
%token <ast> T_VARIABLE "variable (T_VARIABLE)"
9396
%token <ast> T_INLINE_HTML
9497
%token <ast> T_ENCAPSED_AND_WHITESPACE "quoted-string and whitespace (T_ENCAPSED_AND_WHITESPACE)"
@@ -230,7 +233,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
230233
%token T_ERROR
231234

232235
%type <ast> top_statement namespace_name name statement function_declaration_statement
233-
%type <ast> class_declaration_statement trait_declaration_statement
236+
%type <ast> class_declaration_statement trait_declaration_statement legacy_namespace_name
234237
%type <ast> interface_declaration_statement interface_extends_list
235238
%type <ast> group_use_declaration inline_use_declarations inline_use_declaration
236239
%type <ast> mixed_group_use_declaration use_declaration unprefixed_use_declaration
@@ -260,7 +263,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
260263
%type <ast> identifier type_expr_without_static union_type_without_static
261264
%type <ast> inline_function union_type
262265
%type <ast> attributed_statement attributed_class_statement attributed_parameter
263-
%type <ast> attribute_decl attribute attributes
266+
%type <ast> attribute_decl attribute attributes namespace_declaration_name
264267

265268
%type <num> returns_ref function fn is_reference is_variadic variable_modifiers
266269
%type <num> method_modifiers non_empty_member_modifiers member_modifier optional_visibility_modifier
@@ -306,15 +309,29 @@ top_statement_list:
306309
| %empty { $$ = zend_ast_create_list(0, ZEND_AST_STMT_LIST); }
307310
;
308311

312+
/* Name usable in a namespace declaration. */
313+
namespace_declaration_name:
314+
identifier { $$ = $1; }
315+
| T_NAME_QUALIFIED { $$ = $1; }
316+
;
317+
318+
/* Name usable in "use" declarations (loading separator forbidden). */
309319
namespace_name:
310320
T_STRING { $$ = $1; }
311-
| namespace_name T_NS_SEPARATOR T_STRING { $$ = zend_ast_append_str($1, $3); }
321+
| T_NAME_QUALIFIED { $$ = $1; }
322+
;
323+
324+
/* Name usable in "use" declarations (leading separator allowed). */
325+
legacy_namespace_name:
326+
namespace_name { $$ = $1; }
327+
| T_NAME_FULLY_QUALIFIED { $$ = $1; }
312328
;
313329

314330
name:
315-
namespace_name { $$ = $1; $$->attr = ZEND_NAME_NOT_FQ; }
316-
| T_NAMESPACE T_NS_SEPARATOR namespace_name { $$ = $3; $$->attr = ZEND_NAME_RELATIVE; }
317-
| T_NS_SEPARATOR namespace_name { $$ = $2; $$->attr = ZEND_NAME_FQ; }
331+
T_STRING { $$ = $1; $$->attr = ZEND_NAME_NOT_FQ; }
332+
| T_NAME_QUALIFIED { $$ = $1; $$->attr = ZEND_NAME_NOT_FQ; }
333+
| T_NAME_FULLY_QUALIFIED { $$ = $1; $$->attr = ZEND_NAME_FQ; }
334+
| T_NAME_RELATIVE { $$ = $1; $$->attr = ZEND_NAME_RELATIVE; }
318335
;
319336

320337
attribute_decl:
@@ -348,10 +365,10 @@ top_statement:
348365
{ $$ = zend_ast_create(ZEND_AST_HALT_COMPILER,
349366
zend_ast_create_zval_from_long(zend_get_scanned_file_offset()));
350367
zend_stop_lexing(); }
351-
| T_NAMESPACE namespace_name ';'
368+
| T_NAMESPACE namespace_declaration_name ';'
352369
{ $$ = zend_ast_create(ZEND_AST_NAMESPACE, $2, NULL);
353370
RESET_DOC_COMMENT(); }
354-
| T_NAMESPACE namespace_name { RESET_DOC_COMMENT(); }
371+
| T_NAMESPACE namespace_declaration_name { RESET_DOC_COMMENT(); }
355372
'{' top_statement_list '}'
356373
{ $$ = zend_ast_create(ZEND_AST_NAMESPACE, $2, $5); }
357374
| T_NAMESPACE { RESET_DOC_COMMENT(); }
@@ -370,17 +387,13 @@ use_type:
370387
;
371388

372389
group_use_declaration:
373-
namespace_name T_NS_SEPARATOR '{' unprefixed_use_declarations possible_comma '}'
390+
legacy_namespace_name T_NS_SEPARATOR '{' unprefixed_use_declarations possible_comma '}'
374391
{ $$ = zend_ast_create(ZEND_AST_GROUP_USE, $1, $4); }
375-
| T_NS_SEPARATOR namespace_name T_NS_SEPARATOR '{' unprefixed_use_declarations possible_comma '}'
376-
{ $$ = zend_ast_create(ZEND_AST_GROUP_USE, $2, $5); }
377392
;
378393

379394
mixed_group_use_declaration:
380-
namespace_name T_NS_SEPARATOR '{' inline_use_declarations possible_comma '}'
395+
legacy_namespace_name T_NS_SEPARATOR '{' inline_use_declarations possible_comma '}'
381396
{ $$ = zend_ast_create(ZEND_AST_GROUP_USE, $1, $4);}
382-
| T_NS_SEPARATOR namespace_name T_NS_SEPARATOR '{' inline_use_declarations possible_comma '}'
383-
{ $$ = zend_ast_create(ZEND_AST_GROUP_USE, $2, $5); }
384397
;
385398

386399
possible_comma:
@@ -422,8 +435,10 @@ unprefixed_use_declaration:
422435
;
423436

424437
use_declaration:
425-
unprefixed_use_declaration { $$ = $1; }
426-
| T_NS_SEPARATOR unprefixed_use_declaration { $$ = $2; }
438+
legacy_namespace_name
439+
{ $$ = zend_ast_create(ZEND_AST_USE_ELEM, $1, NULL); }
440+
| legacy_namespace_name T_AS T_STRING
441+
{ $$ = zend_ast_create(ZEND_AST_USE_ELEM, $1, $3); }
427442
;
428443

429444
const_list:

Zend/zend_language_scanner.l

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1592,10 +1592,6 @@ NEWLINE ("\r"|"\n"|"\r\n")
15921592
RETURN_TOKEN(T_PAAMAYIM_NEKUDOTAYIM);
15931593
}
15941594

1595-
<ST_IN_SCRIPTING>"\\" {
1596-
RETURN_TOKEN(T_NS_SEPARATOR);
1597-
}
1598-
15991595
<ST_IN_SCRIPTING>"..." {
16001596
RETURN_TOKEN(T_ELLIPSIS);
16011597
}
@@ -2284,6 +2280,22 @@ inline_char_handler:
22842280
RETURN_TOKEN_WITH_VAL(T_ENCAPSED_AND_WHITESPACE);
22852281
}
22862282
2283+
<ST_IN_SCRIPTING>"namespace"("\\"{LABEL})+ {
2284+
RETURN_TOKEN_WITH_STR(T_NAME_RELATIVE, sizeof("namespace\\") - 1);
2285+
}
2286+
2287+
<ST_IN_SCRIPTING>{LABEL}("\\"{LABEL})+ {
2288+
RETURN_TOKEN_WITH_STR(T_NAME_QUALIFIED, 0);
2289+
}
2290+
2291+
<ST_IN_SCRIPTING>"\\"{LABEL}("\\"{LABEL})* {
2292+
RETURN_TOKEN_WITH_STR(T_NAME_FULLY_QUALIFIED, 1);
2293+
}
2294+
2295+
<ST_IN_SCRIPTING>"\\" {
2296+
RETURN_TOKEN(T_NS_SEPARATOR);
2297+
}
2298+
22872299
<ST_IN_SCRIPTING,ST_VAR_OFFSET>{LABEL} {
22882300
RETURN_TOKEN_WITH_STR(T_STRING, 0);
22892301
}

0 commit comments

Comments
 (0)