Skip to content

Treat namespaced names as single token, allow using reserved class names #5720

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

Closed
wants to merge 4 commits into from

Conversation

nikic
Copy link
Member

@nikic nikic commented Jun 15, 2020

RFC: https://wiki.php.net/rfc/namespaced_names_as_token

Instead of treating namespaced names a sequence of T_STRING and T_NS_SEPARATOR tokens, treat them as a single token. In particular, this allows the use of reserved keywords inside namespaced names. At the same time allow using reserved keywords as class, function and constant names -- these cannot be directly used, but they can be used inside a namespaced name (e.g. fully qualified).

This is BC breaking, because whitespace between namespace separators is no longer supported, so Foo \ Bar is no longer considered a legal namespaced name. I consider this a feature, because this avoids bugs that I've seen a couple of times, like:

// Previously this generated an undefined constant diagnostic,
// which is pretty hard to understand if your not familiar with PHP's
// obscure "namespace-relative name" feature.
namespace \Foo;
$x = Foo // <- semicolon missing here
\strlen($bar);

// Interpreted as
$x = Foo\strlen($bar);

@nikic
Copy link
Member Author

nikic commented Jun 15, 2020

Regressions found in top 2k composer packages due to forbidden whitespace in namespaced names:

sylius/sylius/src/Sylius/Bundle/ApiBundle/ApiPlatform/Metadata/Property/Factory/ExtractorPropertyMetadataFactory.php:109
    \ RuntimeException
api-platform/core/src/Metadata/Extractor/AbstractExtractor.php:121
    \ RuntimeException
mck89/peast/lib/Peast/Syntax/Node/JSX/JSXFragment.php:13
    Peast \Syntax\Node\Expression
mck89/peast/lib/Peast/Syntax/Node/JSX/JSXOpeningElement.php:13
    Peast \Syntax\Node\Expression
mck89/peast/lib/Peast/Syntax/Node/JSX/JSXElement.php:13
    Peast \Syntax\Node\Expression

@marcioAlmada
Copy link
Contributor

Hello!

I remember this was the only obstacle that impaired a second version of the context sensitive language RFC, but was considered a bigger BC break at the time. After that change and later parser changes to allow classes, interfaces, functions, traits and constants to have any name I believe only a single edge case happened:

https://3v4l.org/vUVjn

namespace Namespace; // still not possible

namespace/Foo:class; // due to this alternative namespace resolution construct
Foo:class; // which is equivalent to this anyway xD

But that wouldn't be a big deal, probably.

@marcioAlmada
Copy link
Contributor

BTW https://3v4l.org/bOvQJ some constructs re-declared as global functions, could lead to some problems:

// troll.php
function echo(){}
function die(){}
function exit(){}

//

echo('bye');
die('now!');
exit('please?!')

... but also could help making untestable code more testable xD

function echo(){} // not valid
--EXPECTF--
Parse error: syntax error, unexpected 'echo' (T_ECHO), expecting %s in %s on line 9
function echo(){} // valid
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe an error like "Can not redeclare intrinsic PHP construct echo..." makes more sense here? Same for exit, die and print ?

@nikic
Copy link
Member Author

nikic commented Jun 15, 2020

@marcioAlmada I'm intentionally allowing all of these, without special cases. All symbols can be used, they just need to referenced though a namespaced name, such as FooBar\list().

Or is the suggestion here specifically to forbid the function-like language constructs in the global scope only?

@marcioAlmada
Copy link
Contributor

marcioAlmada commented Jun 15, 2020

@marcioAlmada I'm intentionally allowing all of these, without special cases. All symbols can be used, they just need to referenced though a namespaced name, such as FooBar\list().

Or is the suggestion here specifically to forbid the function-like language constructs in the global scope only?

Definitely just function-like language stuff like die.

Or perhaps if declaration is allowed at least don't override PHP die() "call" unless the userland function is explicitly called as \die();

@nikic
Copy link
Member Author

nikic commented Jul 15, 2020

Closing in favor of #5827.

@nikic nikic closed this Jul 15, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants