Skip to content

BUGFIX: Don't create proxy classes for PHP enums#2702

Merged
kdambekalns merged 7 commits into
neos:7.3from
robertlemke:no-proxy-class-for-enums
Mar 15, 2022
Merged

BUGFIX: Don't create proxy classes for PHP enums#2702
kdambekalns merged 7 commits into
neos:7.3from
robertlemke:no-proxy-class-for-enums

Conversation

@robertlemke

@robertlemke robertlemke commented Feb 21, 2022

Copy link
Copy Markdown
Member

This change introduces a check in the proxy class compiler which makes sure that PHP 8.1 enums are not considered as regular classes and are removed from the list of proxyable classes.

How to reproduce:

  1. create an enum, for example in Packages/Acme/Classes/ExampleEnum.php:
namespace Acme;
enum ExampleEnum
{
    case FOO;
    case BAR;
}
  1. let Flow compile classes, the following error will appear:

PHP Fatal error: Cannot declare class Acme\ExampleEnum, because the name is already in use in /application/Data/Temporary/Development/Cache/Code/Flow_Object_Classes/Acme_ExampleEnum.php on line 23

Addresses #2698

This change introduces a check in the proxy class compiler which
makes sure that PHP 8.1 enums are not considered as regular classes
and are removed from the list of proxyable classes.

Addresses neos#2698

@albe albe left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@robertlemke

Copy link
Copy Markdown
Member Author

Looks good, thanks! Can we do something like we did here https://github.com/neos/flow-development-collection/blob/master/Neos.Flow/Classes/ObjectManagement/CompileTimeObjectManager.php#L231 => https://github.com/neos/flow-development-collection/tree/master/Neos.Flow/Tests/Functional/ObjectManagement/Fixtures/PHP8 and add such an enum to the tests conditionally for PHP81?

Yes, more or less – we can't check if the enum was proxied, because it never will be, since the compiler would fail with a fatal error. But yes, we need to back this with a test, so I just pushed one.

@robertlemke

Copy link
Copy Markdown
Member Author

Hmm. Now we need to find a good way to sneak this test in without breaking the < PHP 8.1 runs.

@robertlemke
robertlemke force-pushed the no-proxy-class-for-enums branch from 1797c67 to 536fdaa Compare February 22, 2022 07:59
@robertlemke

Copy link
Copy Markdown
Member Author

Okay, I think I found a solution an force-pushed the commit providing the functional test.

@kdambekalns kdambekalns left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

👍

@kdambekalns

Copy link
Copy Markdown
Member

Sadly it fails for PHP 8.0 with

 syntax error, unexpected identifier "BackedEnumWithMethod"
Type: ParseError
  File:
Packages/Framework/Neos.Flow/Tests/Functional/ObjectManagement/Fixtures/PHP
        8/BackedEnumWithMethod.php
  Line: 19

@robertlemke

Copy link
Copy Markdown
Member Author

Pretty weird, works on my machine™️ …
image

But I'll try to fix it.

@robertlemke

Copy link
Copy Markdown
Member Author

Oh and we should run tests for 8.1 I guess ;-)

@robertlemke
robertlemke requested a review from albe February 22, 2022 11:30
@nezaniel

Copy link
Copy Markdown
Member

@8.1 tests:
I've just merged #2695, here you go :)

@robertlemke

Copy link
Copy Markdown
Member Author

StyleCI doesn't seem to like enums …

@kdambekalns

Copy link
Copy Markdown
Member

StyleCI doesn't seem to like enums …

https://docs.styleci.io/standalone-php#version

@robertlemke
robertlemke requested a review from kitsunet March 1, 2022 10:56

@kitsunet kitsunet left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks good, thanks! Good to have that fixed

@bwaidelich bwaidelich left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think this makes sense, but as written in Slack IMO we should strive towards creating proxies only if they are really needed. And, if a proxy was to be created for a class that is not supported (e.g. an enum) an exception should be thrown.
Otherwise: What happens if you add an AOP aspect for an enum with this change? Will it be ignored?

if ($package instanceof FlowPackageInterface && $shouldRegisterFunctionalTestClasses) {
foreach ($package->getFunctionalTestsClassFiles() as $fullClassName => $path) {
if (PHP_MAJOR_VERSION < 8 && strpos($fullClassName, '\\PHP8\\') !== false) {
if (version_compare(PHP_VERSION, '8.0', '<=') && strpos($fullClassName, '\\PHP8\\') !== false) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Not sure if it's much better, but my PHPStorm suggests to change this line to

Suggested change
if (version_compare(PHP_VERSION, '8.0', '<=') && strpos($fullClassName, '\\PHP8\\') !== false) {
if (PHP_VERSION_ID <= 80000 && strpos($fullClassName, '\\PHP8\\') !== false) {

But apart from that: I'm wondering what these checks actually do?
Could we add some inline comment to explain that?

/**
* A PHP 8.1 value-backed enum with methods
*/
enum BackedEnumWithMethod: string

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I assume that this fixture is not loaded with PHP < 8.1 and doesn't cause any harm that way!?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yes, exactly what you wondered about in CompileTimeObjectManager.php

@robertlemke

Copy link
Copy Markdown
Member Author

What do we do with the failing psalm and styleci tests? They are false-positives, correct?

@kdambekalns

Copy link
Copy Markdown
Member

What do we do with the failing psalm and styleci tests? They are false-positives, correct?

I'll take care…

@kdambekalns

Copy link
Copy Markdown
Member

@kdambekalns
kdambekalns enabled auto-merge March 15, 2022 18:21
@kdambekalns
kdambekalns merged commit d08517b into neos:7.3 Mar 15, 2022
@albe

albe commented Mar 21, 2022

Copy link
Copy Markdown
Contributor

Post-merge 👍 Thanks everyone!

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.

6 participants