Skip to content
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

Fix deprecated nullable areguments #624 #625

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

andypost
Copy link
Contributor

Related to #624

$php = $this->generateTypes($argument->getTypeNode());
$types = $argument->getTypeNode()->getTypes();
$null = $argument->isOptional() && $argument->getDefault() === NULL && \count($types) === 1 && $types[0] !== 'mixed';
$php = $this->generateTypes($argument->getTypeNode(), $null);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

it needs polishing

@jrfnl
Copy link
Contributor

jrfnl commented Aug 19, 2024

Would be lovely if this PR could get finished off and merged (and released!) as anyone who is currently using PHPUnit 9 to assess their own project's PHP 8.4 readiness is faced with a wall of deprecation notices coming from Prophecy.

@andypost Anything you need help with ? Want me to review something ?

@andypost
Copy link
Contributor Author

@jrfnl thank, please help me to improve the code as I don't like amount of \count() added to separate fixes for constructors and return values

@andypost
Copy link
Contributor Author

Personally I do use it as a part of patch for Drupal compatibility issue

@stof
Copy link
Member

stof commented Aug 21, 2024

To make things easier to review, I'd like to see this PR split in 2:

  • one changing the parameter type in the prophecy code itself (which can be the result of running php-cs-fixer's dedicated rule on the codebase)
  • one changing the logic for generated code.

@stof stof added the PHP8.4 label Aug 21, 2024
@andypost
Copy link
Contributor Author

I did split code-style related fixes into #630

@andypost andypost force-pushed the 624-implicitly-nullable-8.4 branch 2 times, most recently from 657ae94 to 210c459 Compare August 21, 2024 15:27
@stof
Copy link
Member

stof commented Aug 21, 2024

Please rebase this branch now that the other PR doing the CS changes on the codebase is merged.

@stof
Copy link
Member

stof commented Aug 21, 2024

@andypost what is the case which requires the change in this PR ? Is it for any nullable optional argument, or only for cases where the original code is relying on an implicit nullable type ?

@andypost
Copy link
Contributor Author

andypost commented Aug 21, 2024

@stof example failures are

The test case code

  public function testUnknownExtension(): void {
    $module_extension_list = $this->prophesize(ModuleExtensionList::class);
    $profile_extension_list = $this->prophesize(ProfileExtensionList::class);
    $theme_extension_list = $this->prophesize(ThemeExtensionList::class);
    $theme_engine_extension_list = $this->prophesize(ThemeEngineExtensionList::class);
    $resolver = new ExtensionPathResolver(
      $module_extension_list->reveal(),
      $profile_extension_list->reveal(),
      $theme_extension_list->reveal(),
      $theme_engine_extension_list->reveal()
    );

The mocked class

public function __construct($root, $type, CacheBackendInterface $cache,

produce following output

    /builds/issue/drupal-3427903/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassCreator.php(44)
    : eval()'d code:5
    Double\Drupal\Core\Extension\ModuleExtensionList\P1::__construct():
    Implicitly marking parameter $cache as nullable is deprecated, the explicit
    nullable type must be used instead
    
    Triggered by:
    
    *
    Drupal\KernelTests\Core\Bootstrap\ExtensionPathResolverTest::testUnknownExtension
     
    /builds/issue/drupal-3427903/core/tests/Drupal/KernelTests/Core/Bootstrap/ExtensionPathResolverTest.php:99

@andypost
Copy link
Contributor Author

andypost commented Aug 21, 2024

As I get it... when class with required typed constructor argument is mocked, prophecy making argument nullable but somehow without leading ? on PHP 8.4

@stof
Copy link
Member

stof commented Aug 21, 2024

@andypost can you show the class definition of ModuleExtensionList ?

@andypost
Copy link
Contributor Author

@andypost
Copy link
Contributor Author

Fixed nullable types in spec and now it pass

@stof
Copy link
Member

stof commented Aug 22, 2024

@andypost if you update the $container_modules_info argument of the ModuleExtensionList constructor to avoid using an implicit nullable type, does the double still use an implicit nullable type (without this PR applied) ?

@andypost
Copy link
Contributor Author

@stof The $container_modules_info supposed to have default value and is not nullable and without patch reveal() just setting to null the CacheBackendInterface $cache but so my patch adding ? for such cases

@andypost
Copy link
Contributor Author

The error is the same

    Double\Drupal\Core\Extension\ModuleExtensionList\P1::__construct():
    Implicitly marking parameter $cache as nullable is deprecated, the explicit
    nullable type must be used instead

{
if (!$typeNode->getTypes()) {
return '';
}

// When we require PHP 8 we can stop generating ?foo nullables and remove this first block
if ($typeNode->canUseNullShorthand()) {
if ($typeNode->canUseNullShorthand() || $nullable) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

this place exactly is not working, it just making all arguments nullable (optional) but if the type defined for one then no ? is added

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Specifically for case when type is mixed and no null (PHP 8.2) defined in intersection (PHP 8.1)

$nullable = FALSE;
}
}
$php = $this->generateTypes($argument->getTypeNode(), $nullable);
Copy link
Contributor Author

@andypost andypost Aug 22, 2024

Choose a reason for hiding this comment

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

new argument required because $argument->getTypeNode() has no access to default value and optional property

@stof
Copy link
Member

stof commented Aug 22, 2024

OK, apparently, those errors come from the DisableConstructorPatch which aims at making all constructor arguments optional.

the right fix is to update the implementation of that class patch so that it makes all arguments nullable as well (by updating the argument type) instead of adding a null default on non-nullable types. This would be much cleaner than making the code generator turn implicit nullable types to explicit ones.

@andypost
Copy link
Contributor Author

@stof I can't make such big refactoring and need help to cover all cases

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.

3 participants