Switch long-form single-line assign and null coalesce (= ??) to null coalesce assign operator (??=)

Created on 31 January 2024, 10 months ago
Updated 26 March 2024, 8 months ago

Problem/Motivation

The purpose is to use null coalescing assignment operator ??=. This issue corresponds to the particular case A where the original code is one line. Typically,
$A = $A ?? $B;
changed to,
$A ??= $B;

For example, in core/modules/jsonapi/src/Normalizer/ResourceObjectNormalizer.php, in function getNormalization,
$base['links'] = $base['links'] ?? $this->serializer->normalize($object->getLinks(), $format, $context)->omitIfEmpty();
could be changed in,
$base['links'] ??= $this->serializer->normalize($object->getLinks(), $format, $context)->omitIfEmpty();

( #20 📌 Switch long-form single-line assign and null coalesce (= ??) to null coalesce assign operator (??=) Needs work : This issue has been changed from general to a particular case. See the parent issue for the general purpose.)

Steps to reproduce

Proposed resolution

From #2 📌 Switch long-form single-line assign and null coalesce (= ??) to null coalesce assign operator (??=) Needs work ,

.... assume there are many similar changes we could make across all of core, and ideally a coding standards sniff we could enable to prevent this code from creeping back in.

Ideally we would change all instances of this across core in one go,

In this case the code sniffer rule already exists. Use phpcs with rule RequireNullCoalesceEqualOperator from SlevomatCodingStandard:
phpcs --standard=SlevomatCodingStandard --sniffs=SlevomatCodingStandard.ControlStructures.RequireNullCoalesceEqualOperator core

Merge request link

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

📌 Task
Status

Postponed

Version

11.0 🔥

Component
Other 

Last updated about 5 hours ago

Created by

🇫🇷France Chris64 France

Live updates comments and jobs are added and updated live.
  • Needs issue summary update

    Issue summaries save everyone time if they are kept up-to-date. See Update issue summary task instructions.

Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @Chris64
  • Status changed to Needs work 10 months ago
  • 🇬🇧United Kingdom longwave UK

    Thanks for the suggestion. I assume there are many similar changes we could make across all of core, and ideally a coding standards sniff we could enable to prevent this code from creeping back in.

    Ideally we would change all instances of this across core in one go, please read the issue scoping guidelines for more info: https://www.drupal.org/docs/develop/issues/issue-procedures-and-etiquett...

    If you can help expand the scope of this issue, please do!

  • 🇮🇳India anchal_gupta

    I have uploaded the patch.
    Please review

  • 🇫🇷France Chris64 France

    Indeed, that is clear. Here the idea was to suggest the principle with a concrete case. The general purpose is necessary but more difficult.

  • 🇫🇷France Chris64 France

    As first sniffer,
    grep -Prn '^\s*([^\s]+)\s=\s\1\s\?\?\s.+$'

  • Status changed to Closed: duplicate 10 months ago
  • I think this issue is the initiative.

  • Status changed to Needs work 10 months ago
  • Then again, maybe not. This issue may be about using one-line assignment statements instead of multi-line conditionals. Is it?

  • 🇫🇷France Chris64 France

    Yes, reducing the number of instruction lines. When it is possible.

  • 🇫🇷France Chris64 France

    Two files corresponding to patches giving an idea of what kind of code transformations the rule gives. One is small, A, grouping uniligne code, the other is bigger, B, grouping multiligne code. All the code changes here are produced automatically via a sed command (one command, one file). It is the moment for comments. Is it right? Is it complete? Is reasonable?

  • last update 9 months ago
    Patch Failed to Apply
  • last update 9 months ago
    Patch Failed to Apply
  • Status changed to Needs review 9 months ago
  • Status changed to Needs work 9 months ago
  • 🇺🇸United States smustgrave

    Title and issue summary mention just layout_discovery.module but the patches appear to be entire drupal so tagging for those to be updated.

    Also recommended to use MRs

  • Status changed to Needs review 9 months ago
  • 🇫🇷France Chris64 France

    Also recommended to use MRs

    I thought about it, but the work needs a first general code review, and a patch file seems for me a simple means to do it. If it will be, look right try a MR now, or some things likes, to big must be cut, or, some rules look wrong.

  • Status changed to Needs work 9 months ago
  • The Needs Review Queue Bot tested this issue.

    While you are making the above changes, we recommend that you convert this patch to a merge request . Merge requests are preferred over patches. Be sure to hide the old patch files as well. (Converting an issue to a merge request without other contributions to the issue will not receive credit.)

  • First commit to issue fork.
  • Merge request !6743Issue#3418494: Update as null coalescing. → (Open) created by sakthi_dev
  • Status changed to Needs review 9 months ago
  • 🇮🇳India sakthi_dev

    Created an MR against 11.x branch. Please review.

  • Pipeline finished with Success
    9 months ago
    Total: 463s
    #101627
  • 🇫🇷France Chris64 France

    @sakthi_dev your MR seems correspond with the patch 9A. Agree with this choice. Thank you for your MR.

  • 🇫🇷France Chris64 France

    May be this issue would be more easy to manage with a parent issue with children corresponding to the different cases. Actually two.

  • 🇫🇷France Chris64 France

    Issue changed from general to the particular simpler case A corresponding to the MR. See the parent issue 📌 Use null coalescing assignment operator Active for the general purpose.

  • Status changed to Needs work 9 months ago
  • 🇦🇺Australia dpi Perth, Australia

    Can we simply resolve to run rector with the result of the relevant rector rule: https://github.com/rectorphp/rector/blob/main/docs/rector_rules_overview... : Rector\Php74\Rector\Assign\NullCoalescingOperatorRector, instead of sed per IS.

    That way we have an easily testable/reproducable set of changes.

    I'm seeing at least twice as many changes as the MR, compared to a local rector run.

  • 🇫🇷France Chris64 France

    You are right @dpi! Rector is much better. Indeed, some cases was missed...

  • Pipeline finished with Success
    9 months ago
    Total: 481s
    #104484
  • Status changed to Needs review 9 months ago
  • 🇫🇷France Chris64 France

    13 missing files found, in core/lib. Got with rector.

  • 🇺🇸United States smustgrave

    Should we work on some checker to catch these before merging so they don't resurface?

  • 🇫🇷France Chris64 France

    @smustgrave, this particular case is efficiently managed by rector. As indicated by @dpi in #23 📌 Switch long-form single-line assign and null coalesce (= ??) to null coalesce assign operator (??=) Needs work . The general purpose is some thing else. I am in favour of dividing the general problem into different particular cases.

  • 🇫🇷France Chris64 France

    @smustgrave, for phpcs, a rule exists about this case,
    slevomat/coding-standard/SlevomatCodingStandard/Sniffs/ControlStructures/RequireNullCoalesceEqualOperatorSniff
    but is missing in drupal/coder/coder_sniffer/Drupal/ruleset.xml,
    <rule ref="SlevomatCodingStandard.ControlStructures.RequireNullCoalesceEqualOperator" />
    I think this is this case since the rule message is,
    Use "??=" operator instead of "=" and "??

  • Status changed to Needs work 8 months ago
  • The Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".

    This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

    Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

  • 🇫🇷France Chris64 France

    Use phpcs with rule RequireNullCoalesceEqualOperator from SlevomatCodingStandard:
    phpcs --standard=SlevomatCodingStandard --sniffs=SlevomatCodingStandard.ControlStructures.RequireNullCoalesceEqualOperator core

  • 🇫🇷France Chris64 France

    1 test error occurs. Some thing wrong happen with,
    Drupal\Tests\Composer\Plugin\Scaffold\Functional\ManageGitIgnoreTest::testUnmanagedGitIgnoreWhenGitNotAvailable
    in core/tests/Drupal/Tests/Composer/Plugin/Scaffold/Functional/ManageGitIgnoreTest.php line 253,
    $this->assertEquals($expected, $output);
    The $expected is not equal to the $output. In this latter an error message exists,
    Composer could not detect the root package (fixtures/drupal-composer-drupal-project) version, defaulting to '1.0.0'. See https://getcomposer.org/root-version

  • 🇫🇷France Chris64 France

    The test error message,

    Drupal.Tests.Composer.Plugin.Scaffold.Functional.ManageGitIgnoreTest
    Name testUnmanagedGitIgnoreWhenGitNotAvailable
    File core/tests/Drupal/Tests/Composer/Plugin/Scaffold/Functional/ManageGitIgnoreTest.php
    Execution time 448.86ms
    System output
    
    Drupal\Tests\Composer\Plugin\Scaffold\Functional\ManageGitIgnoreTest::testUnmanagedGitIgnoreWhenGitNotAvailable
    Failed asserting that two strings are equal.
    --- Expected
    +++ Actual
    @@ @@
    -'Scaffolding files for fixtures/drupal-assets-fixture:\n
    +'Composer could not detect the root package (fixtures/drupal-composer-drupal-project) version, defaulting to '1.0.0'. See https://getcomposer.org/root-version\n
    +Scaffolding files for fixtures/drupal-assets-fixture:\n
       - Copy [web-root]/.csslintrc from assets/.csslintrc\n
       - Copy [web-root]/.editorconfig from assets/.editorconfig\n
       - Copy [web-root]/.eslintignore from assets/.eslintignore\n
    
    vendor/phpunit/phpunit/src/Framework/Constraint/Equality/IsEqual.php:94
    core/tests/Drupal/Tests/Composer/Plugin/Scaffold/Functional/ManageGitIgnoreTest.php:253
    vendor/phpunit/phpunit/src/Framework/TestResult.php:728
    vendor/phpunit/phpunit/src/Framework/TestSuite.php:684
    vendor/phpunit/phpunit/src/TextUI/TestRunner.php:651
    vendor/phpunit/phpunit/src/TextUI/Command.php:144
    vendor/phpunit/phpunit/src/TextUI/Command.php:97
  • 🇫🇷France Chris64 France

    I don't see the relation with ??=.

  • 🇳🇱Netherlands spokje

    I don't see the relation with ??=.

    There is indeed no relation, HEAD was broken for a while 🐛 ManageGitIgnoreTest failing in HEAD RTBC .
    Is fixed now, a rebase should make the error go away.

  • 🇫🇷France Chris64 France

    The $output comes from,

        // Confirm that 'git' is no longer available.
        $output = [];
        exec('git --help', $output, $status);
        $this->assertEquals(127, $status);
        // Run the scaffold command.
        $output = $this->mustExec('composer drupal:scaffold 2>&1', NULL);

    And the composer error comes from the latter line.

    From https://getcomposer.org/root-version the error message correspond to the case 4. The information can not come from case 3, since git is not available here. Therefore, to provide the information remain either case 1, through the version key in composer.json, or case 2, from the COMPOSER_ROOT_VERSION environment variable. Else the message is right, and the the $expected is erroneous with this message missing.

  • 🇫🇷France Chris64 France

    Thank you @Spokje for the information. You mean #30 📌 Switch long-form single-line assign and null coalesce (= ??) to null coalesce assign operator (??=) Needs work ? Normally it is a new rebased version.

  • Pipeline finished with Failed
    8 months ago
    Total: 12334s
    #120222
  • 🇫🇷France Chris64 France

    Okay @Spokje, that is clear.

  • Pipeline finished with Success
    8 months ago
    Total: 484s
    #122602
  • Status changed to Needs review 8 months ago
  • 🇫🇷France Chris64 France

    MR Mergeable. Need review. Not a straight line, but seems okay now. Rebased on #3428032 to pass the test.

  • Status changed to Needs work 8 months ago
  • The Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".

    This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

    Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

  • Status changed to Postponed 8 months ago
Production build 0.71.5 2024