8000 Add enum_exists() as well as UnitEnum and BackedEnum interfaces by thekid · Pull Request #261 · xp-framework/core · GitHub
[go: up one dir, main page]

Skip to content

Add enum_exists() as well as UnitEnum and BackedEnum interfaces #261

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

Merged
merged 16 commits into from
Mar 10, 2021

Conversation

thekid
Copy link
Member
@thekid thekid commented Mar 8, 2021

Forwards compatibility with PHP 8.1 enumerations

  • Declare enum_exists() function
  • Declare UnitEnum and BackedEnum interfaces
  • Extend XPClass::isEnum() to also recognize PHP 8.1 enums
  • Extend Enum::valuesOf() and Enum::valuesOf() to return PHP 8.1 enum cases
  • Test all this with a PHP 8.1 version with Implement enums php/php-src#6489 applied

See https://wiki.php.net/rfc/enumerations

@thekid
Copy link
Member Author
thekid commented Mar 8, 2021

Test all this with a PHP 8.1 version with [...enum support...]

Obviously, since Enum is now a reserved word, one cannot declare a class with that. This breaks lang.Enum.

# Patch & compile
thekid@Surface:~/bin/php$ curl https://patch-diff.githubusercontent.com/raw/php/php-src/pull/6489.patch | patch -p1
thekid@Surface:~/bin/php$ make clean && ./buildconf && ./config.nice && make
# ...

# Verify enum support is available
thekid@Surface:~/bin/php$ ./sapi/cli/php -r 'enum SortOrder { case ASC; case DESC; } var_dump(SortOrder::ASC);'
enum(SortOrder::ASC)

# Run tests
thekid@Surface:[...]/devel/xp/core$ XP_RT=master xp xp.unittest.Runner src/test/config/unittest/core.ini
Uncaught exception: ParseError (syntax error, unexpected token "enum", expecting identifier)
  at <source> [line 10 of ./src/main/php/lang/Enum.class.php]
# ...

We would need to rename the Enum class to XPEnum (following the XPClass idiom). We should be able to do this BC break free for PHP 7 and PHP 8.0 by aliasing Enum to XPEnum.

@iluuu1994
Copy link

Obviously, since Enum is now a reserved word, one cannot declare a class with that. This breaks lang.Enum.

We've actually changed this recently to ease migration.

https://wiki.php.net/rfc/enumerations

Thanks to a clever trick from Nikita (discussed after the RFC was approved), “enum” is not a reserved word on its own. That means it is still a legal name for a class/interface/trait at this time. It will likely be converted into a full keyword at some point in the future, but this RFC does not specify that timeline. As a side effect, comments are not supported between “enum” and the Enum name, which is of little consequence in practice.

So your class name should not break.

thekid added 2 commits March 9, 2021 21:36
Should also be done in unittest library one XP core is released with
this change!
@thekid
Copy link
Member Author
thekid commented Mar 9, 2021

So your class name should not break.

There is a glitch in this implementation, @iluuu1994:

# Works as expected
thekid@Surface:~/bin/php$ ./sapi/cli/php -r 'class Enum { }'

# Breaks
thekid@Surface:~/bin/php$ ./sapi/cli/php -r 'interface Value { } class Enum implements Value { }'

Parse error: syntax error, unexpected token "enum", expecting identifier in Command line code on line 1`

This is the trick you're referencing:

/*
 * The enum keyword must be followed by whitespace and another identifier.
 * This avoids the BC break of using enum in classes, namespaces, functions and constants.
 */
<ST_IN_SCRIPTING>"enum"{WHITESPACE}[a-zA-Z_\x80-\xff] {
        yyless(4);
        RETURN_TOKEN_WITH_IDENT(T_ENUM);
}

The problem is that in class Enum implements Value, the string implements fulfills this rule, yielding the following tokens: T_CLASS T_ENUM T_IMPLEMENTS T_STRING("Value"), however, the class declaration rule expects T_CLASS T_STRING, thus causing this parse error.

@iluuu1994
Copy link

Oh right, thanks for the heads up. Glad you tested that.

@iluuu1994
Copy link

@thekid Pushed a fix, does this resolve the problem?

@thekid
Copy link
Member Author
thekid commented Mar 10, 2021

@thekid Pushed a fix, does this resolve the problem?

Yes, it does:

# After applying the newer patch:
thekid@Surface:~/bin/php$ ./sapi/cli/php -r 'interface Value { } class Enum implements Value { } var_dump(new Enum());'
object(Enum)#1 (0) {
}

Thanks @iluuu1994

@iluuu1994
Copy link

Great! Thanks for testing 🙂

@thekid
Copy link
Member Author
thekid commented Mar 10, 2021

Test results

PHP 8.0:

$ XP_RT=8.0 xp test src/test/php/net/xp_framework/unittest/core/EnumTest.class.php
# ...

♥: 41/45 run (4 skipped), 41 succeeded, 0 failed
Memory used: 2335.88 kB (2544.44 kB peak)
Time taken: 0.079 seconds

PHP 8.1 with enums:

$ XP_RT=master xp xp.unittest.Runner src/test/php/net/xp_framework/unittest/core/EnumTest.class.php
# ...

♥: 45/45 run (0 skipped), 45 succeeded, 0 failed
Memory used: 2250.23 kB (2646.16 kB peak)
Time taken: 0.065 seconds

@thekid thekid merged commit b99e73f into xp-framework:master Mar 10, 2021
@thekid thekid deleted the feature/php-enums-fc branch March 10, 2021 17:54
@thekid
Copy link
Member Author
thekid commented Mar 10, 2021

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants
0