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

Require Null Safe Object operator #255

Merged
merged 2 commits into from Jul 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/continuous-integration.yml
Expand Up @@ -128,6 +128,7 @@ jobs:
php-version:
- "7.1"
- "7.4"
- "8.0"

steps:
- name: "Checkout"
Expand Down
25 changes: 17 additions & 8 deletions Makefile
@@ -1,27 +1,36 @@
.PHONY: test test-report test-fix update-compatibility-patch

PHP_74_OR_NEWER:=$(shell php -r "echo (int) version_compare(PHP_VERSION, '7.4', '>=');")
PHP_VERSION:=$(shell php -r "echo PHP_MAJOR_VERSION.PHP_MINOR_VERSION;")
PATCH_FILE="tests/php$(PHP_VERSION)-compatibility.patch"

test: test-report test-fix

test-report: vendor
@if [ $(PHP_74_OR_NEWER) -eq 1 ]; then git apply tests/php-compatibility.patch; fi
@vendor/bin/phpcs `find tests/input/* | sort` --report=summary --report-file=phpcs.log; diff -u tests/expected_report.txt phpcs.log; if [ $$? -ne 0 ]; then if [ $(PHP_74_OR_NEWER) -eq 1 ]; then git apply -R tests/php-compatibility.patch; fi; exit 1; fi
@if [ $(PHP_74_OR_NEWER) -eq 1 ]; then git apply -R tests/php-compatibility.patch; fi
@if [ -f "$(PATCH_FILE)" ]; then git apply $(PATCH_FILE) ; fi
@vendor/bin/phpcs `find tests/input/* | sort` --report=summary --report-file=phpcs.log; diff -u tests/expected_report.txt phpcs.log; if [ $$? -ne 0 ] && [ -f "$(PATCH_FILE)" ]; then git apply -R $(PATCH_FILE) ; exit 1; fi
@if [ -f "$(PATCH_FILE)" ]; then git apply -R $(PATCH_FILE) ; fi

test-fix: vendor
@if [ $(PHP_74_OR_NEWER) -eq 1 ]; then git apply tests/php-compatibility.patch; fi
@if [ -f "$(PATCH_FILE)" ]; then git apply $(PATCH_FILE) ; fi
@cp -R tests/input/ tests/input2/
@vendor/bin/phpcbf tests/input2; diff -u tests/input2 tests/fixed; if [ $$? -ne 0 ]; then rm -rf tests/input2/ && if [ $(PHP_74_OR_NEWER) -eq 1 ]; then git apply -R tests/php-compatibility.patch; fi; exit 1; fi
@rm -rf tests/input2/ && if [ $(PHP_74_OR_NEWER) -eq 1 ]; then git apply -R tests/php-compatibility.patch; fi
@vendor/bin/phpcbf tests/input2; diff -u tests/input2 tests/fixed; if [ $$? -ne 0 ]; then rm -rf tests/input2/; if [ -f "$(PATCH_FILE)" ]; then git apply -R $(PATCH_FILE) ; fi; exit 1; fi
@rm -rf tests/input2/;
@if [ -f "$(PATCH_FILE)" ]; then git apply -R $(PATCH_FILE) ; fi

update-compatibility-patch:
update-compatibility-patch-74:
@git apply tests/php-compatibility.patch
@printf "Please open your editor and apply your changes\n"
@until [ "$${compatibility_resolved}" == "y" ]; do read -p "Have finished your changes (y|n)? " compatibility_resolved; done && compatibility_resolved=
@git diff -- tests/expected_report.txt tests/fixed > .tmp-patch && mv .tmp-patch tests/php-compatibility.patch && git apply -R tests/php-compatibility.patch
@git commit -m 'Update compatibility patch' tests/php-compatibility.patch

update-compatibility-patch-80:
@git apply tests/php80-compatibility.patch
@printf "Please open your editor and apply your changes\n"
@until [ "$${compatibility_resolved}" == "y" ]; do read -p "Have finished your changes (y|n)? " compatibility_resolved; done && compatibility_resolved=
@git diff -- tests/expected_report.txt tests/fixed > .tmp-patch-80 && mv .tmp-patch-80 tests/php80-compatibility.patch && git apply -R tests/php80-compatibility.patch
@git commit -m 'Update compatibility patch' tests/php80-compatibility.patch

vendor: composer.json
composer update
touch -c vendor
2 changes: 2 additions & 0 deletions lib/Doctrine/ruleset.xml
Expand Up @@ -266,6 +266,8 @@
<rule ref="SlevomatCodingStandard.ControlStructures.RequireNullCoalesceEqualOperator"/>
<!-- Require usage of null coalesce operator when possible -->
<rule ref="SlevomatCodingStandard.ControlStructures.RequireNullCoalesceOperator"/>
<!-- Require usage of null safe operator when possible -->
<rule ref="SlevomatCodingStandard.ControlStructures.RequireNullSafeObjectOperator"/>
<!-- Forbid usage of conditions when a simple return can be used -->
<rule ref="SlevomatCodingStandard.ControlStructures.UselessIfConditionWithReturn"/>
<!-- Forbid usage of boolean-only ternary operator usage (e.g. $foo ? true : false) -->
Expand Down
5 changes: 5 additions & 0 deletions tests/fixed/null_safe_operator.php
@@ -0,0 +1,5 @@
<?php

declare(strict_types=1);

$var = $object === null ? null : $object->property;
5 changes: 5 additions & 0 deletions tests/input/null_safe_operator.php
@@ -0,0 +1,5 @@
<?php

declare(strict_types=1);

$var = $object === null ? null : $object->property;
File renamed without changes.
165 changes: 165 additions & 0 deletions tests/php80-compatibility.patch
@@ -0,0 +1,165 @@
diff --git a/tests/expected_report.txt b/tests/expected_report.txt
index c644926..d0f0a44 100644
--- a/tests/expected_report.txt
+++ b/tests/expected_report.txt
@@ -15,18 +15,19 @@ tests/input/ControlStructures.php 28 0
tests/input/doc-comment-spacing.php 11 0
tests/input/duplicate-assignment-variable.php 1 0
tests/input/EarlyReturn.php 6 0
-tests/input/example-class.php 38 0
+tests/input/example-class.php 42 0
tests/input/forbidden-comments.php 14 0
tests/input/forbidden-functions.php 6 0
tests/input/inline_type_hint_assertions.php 7 0
tests/input/LowCaseTypes.php 2 0
tests/input/namespaces-spacing.php 7 0
-tests/input/NamingCamelCase.php 6 0
+tests/input/NamingCamelCase.php 9 0
tests/input/negation-operator.php 2 0
-tests/input/new_with_parentheses.php 18 0
+tests/input/new_with_parentheses.php 19 0
tests/input/not_spacing.php 8 0
-tests/input/null_coalesce_equal_operator.php 1 0
+tests/input/null_coalesce_equal_operator.php 5 0
tests/input/null_coalesce_operator.php 3 0
+tests/input/null_safe_operator.php 1 0
tests/input/optimized-functions.php 1 0
tests/input/PropertyTypeHintSpacing.php 6 0
tests/input/return_type_on_closures.php 21 0
@@ -39,15 +40,15 @@ tests/input/superfluous-naming.php 11 0
tests/input/test-case.php 8 0
tests/input/trailing_comma_on_array.php 1 0
tests/input/traits-uses.php 11 0
-tests/input/type-hints.php 4 0
+tests/input/type-hints.php 5 0
tests/input/UnusedVariables.php 1 0
tests/input/use-ordering.php 1 0
tests/input/useless-semicolon.php 2 0
tests/input/UselessConditions.php 20 0
----------------------------------------------------------------------
-A TOTAL OF 377 ERRORS AND 0 WARNINGS WERE FOUND IN 41 FILES
+A TOTAL OF 391 ERRORS AND 0 WARNINGS WERE FOUND IN 42 FILES
----------------------------------------------------------------------
-PHPCBF CAN FIX 313 OF THESE SNIFF VIOLATIONS AUTOMATICALLY
+PHPCBF CAN FIX 327 OF THESE SNIFF VIOLATIONS AUTOMATICALLY
----------------------------------------------------------------------


diff --git a/tests/fixed/NamingCamelCase.php b/tests/fixed/NamingCamelCase.php
index 57d9f2b..5493471 100644
--- a/tests/fixed/NamingCamelCase.php
+++ b/tests/fixed/NamingCamelCase.php
@@ -6,14 +6,11 @@ namespace Example;

class NamingCamelCase
{
- /** @var mixed */
- public $A;
+ public mixed $A;

- /** @var mixed */
- protected $B;
+ protected mixed $B;

- /** @var mixed */
- private $C;
+ private mixed $C;

public function fcn(string $A): void
{
diff --git a/tests/fixed/example-class.php b/tests/fixed/example-class.php
index 998e51d..b47d358 100644
--- a/tests/fixed/example-class.php
+++ b/tests/fixed/example-class.php
@@ -25,17 +25,14 @@ class Example implements IteratorAggregate
{
private const VERSION = PHP_VERSION - (PHP_MINOR_VERSION * 100) - PHP_PATCH_VERSION;

- /** @var int|null */
- private $foo;
+ private ?int $foo = null;

/** @var string[] */
- private $bar;
+ private array $bar;

- /** @var bool */
- private $baz;
+ private bool $baz;

- /** @var ControlStructureSniff|int|string|null */
- private $baxBax;
+ private ControlStructureSniff|int|string|null $baxBax = null;

public function __construct(?int $foo = null, array $bar = [], bool $baz = false, $baxBax = 'unused')
{
diff --git a/tests/fixed/new_with_parentheses.php b/tests/fixed/new_with_parentheses.php
index 6e81bbe..47a06ec 100644
--- a/tests/fixed/new_with_parentheses.php
+++ b/tests/fixed/new_with_parentheses.php
@@ -24,5 +24,5 @@ $y = [new stdClass()];

$z = new stdClass() ? new stdClass() : new stdClass();

-$q = $q ?: new stdClass();
-$e = $e ?? new stdClass();
+$q = $q ?: new stdClass();
+$e ??= new stdClass();
diff --git a/tests/fixed/null_coalesce_equal_operator.php b/tests/fixed/null_coalesce_equal_operator.php
index b997469..6703d30 100644
--- a/tests/fixed/null_coalesce_equal_operator.php
+++ b/tests/fixed/null_coalesce_equal_operator.php
@@ -2,12 +2,12 @@

declare(strict_types=1);

-$bar = $bar ?? 'bar';
+$bar ??= 'bar';

-$bar['baz'] = $bar['baz'] ?? 'baz';
+$bar['baz'] ??= 'baz';

-$bar = $bar ?? 'bar';
+$bar ??= 'bar';

-$object->property = $object->property ?? 'Default Value';
+$object->property ??= 'Default Value';

-Test::$foo = Test::$foo ?? 123;
+Test::$foo ??= 123;
diff --git a/tests/fixed/null_coalesce_operator.php b/tests/fixed/null_coalesce_operator.php
index 8846dd1..51c361c 100644
--- a/tests/fixed/null_coalesce_operator.php
+++ b/tests/fixed/null_coalesce_operator.php
@@ -4,7 +4,7 @@ declare(strict_types=1);

$foo = $_GET['foo'] ?? 'foo';

-$bar = $bar ?? 'bar';
+$bar ??= 'bar';

$bar = $bar['baz'] ?? 'baz';

diff --git a/tests/fixed/null_safe_operator.php b/tests/fixed/null_safe_operator.php
index 5bbb636..7ce8a3d 100644
--- a/tests/fixed/null_safe_operator.php
+++ b/tests/fixed/null_safe_operator.php
@@ -2,4 +2,4 @@

declare(strict_types=1);

-$var = $object === null ? null : $object->property;
+$var = $object?->property;
diff --git a/tests/fixed/type-hints.php b/tests/fixed/type-hints.php
index 0e952fc..9824fb0 100644
--- a/tests/fixed/type-hints.php
+++ b/tests/fixed/type-hints.php
@@ -10,7 +10,7 @@ use Traversable;
class TraversableTypeHints
{
/** @var Traversable */
- private $parameter;
+ private Traversable $parameter;

/**
* @param Iterator $iterator