|
@@ -0,0 +1,361 @@
|
|
|
+--TEST--
|
|
|
+PHP 8.0 test.
|
|
|
+--RULESET--
|
|
|
+{
|
|
|
+ "@PHP80Migration": true,
|
|
|
+ "@PHP80Migration:risky": true,
|
|
|
+ "@PhpCsFixer": true,
|
|
|
+ "@PhpCsFixer:risky": true,
|
|
|
+ "phpdoc_to_return_type": true
|
|
|
+}
|
|
|
+--REQUIREMENTS--
|
|
|
+{"php": 80000}
|
|
|
+--EXPECT--
|
|
|
+<?php
|
|
|
+
|
|
|
+declare(strict_types=1);
|
|
|
+
|
|
|
+// https://wiki.php.net/rfc/named_params
|
|
|
+array_fill(start_index: 0, num: 100, value: 50);
|
|
|
+htmlspecialchars($string, double_encode: false);
|
|
|
+array_slice($array, $offset, $length, preserve_keys: true);
|
|
|
+new ParamNode($name, variadic: $isVariadic, byRef: $passByRef);
|
|
|
+array_foobar(array: $value); // reserved keyword as parameter name!
|
|
|
+
|
|
|
+// https://wiki.php.net/rfc/nullsafe_operator
|
|
|
+$country = $session?->user?->getAddress()?->country;
|
|
|
+
|
|
|
+// https://wiki.php.net/rfc/attributes_v2
|
|
|
+// https://wiki.php.net/rfc/attribute_amendments
|
|
|
+// https://wiki.php.net/rfc/shorter_attribute_syntax
|
|
|
+// https://wiki.php.net/rfc/shorter_attribute_syntax_change
|
|
|
+#[MyAttribute]
|
|
|
+#[\MyExample\MyAttribute]
|
|
|
+#[MyAttribute(1234)]
|
|
|
+#[MyAttribute(value: 1234)]
|
|
|
+#[MyAttribute(MyAttribute::VALUE)]
|
|
|
+#[MyAttribute(['key' => 'value'])]
|
|
|
+#[MyAttribute(100 + 200)]
|
|
|
+#[Attribute(Attribute::TARGET_METHOD | Attribute::TARGET_FUNCTION)]
|
|
|
+#[MyAttribute(1234), MyAttribute(5678)]
|
|
|
+class PostsController
|
|
|
+{
|
|
|
+ #[Route('/api/posts/{id}', methods: ['GET'])]
|
|
|
+ public function get($id): void
|
|
|
+ {
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+$object = new #[ExampleAttribute] class()
|
|
|
+{
|
|
|
+ #[ExampleAttribute]
|
|
|
+ public function foo(#[ExampleAttribute] $bar): void
|
|
|
+ {
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+// https://wiki.php.net/rfc/union_types_v2
|
|
|
+class Number
|
|
|
+{
|
|
|
+ private int | float | null $number;
|
|
|
+
|
|
|
+ public function setNumber(int | float $number): void
|
|
|
+ {
|
|
|
+ $this->number = $number;
|
|
|
+ }
|
|
|
+
|
|
|
+ public function getNumber(): int | float | null
|
|
|
+ {
|
|
|
+ return $this->number;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// https://wiki.php.net/rfc/class_name_literal_on_object
|
|
|
+// nothing we can do
|
|
|
+
|
|
|
+// https://wiki.php.net/rfc/static_return_type
|
|
|
+class T
|
|
|
+{
|
|
|
+ public function Foo(object $A): ?static
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
+ /** @return static */
|
|
|
+ public function something(): static
|
|
|
+ {
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// https://wiki.php.net/rfc/variable_syntax_tweaks
|
|
|
+// nothing we can do
|
|
|
+
|
|
|
+// https://wiki.php.net/rfc/trailing_comma_in_parameter_list
|
|
|
+function foo(string $param = null, ): void
|
|
|
+{
|
|
|
+}
|
|
|
+call_user_func('foo', 1, );
|
|
|
+
|
|
|
+// https://wiki.php.net/rfc/trailing_comma_in_closure_use_list
|
|
|
+$foo1a = function (): void {};
|
|
|
+$foo1b = function (): void {};
|
|
|
+$foo2 = function () use ($bar, $baz, ): void { echo $bar.$baz; };
|
|
|
+
|
|
|
+// https://wiki.php.net/rfc/mixed_type_v2
|
|
|
+class T_Mixed
|
|
|
+{
|
|
|
+ public function Foo(mixed $a): mixed
|
|
|
+ {
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// https://wiki.php.net/rfc/throw_expression
|
|
|
+if (1) {
|
|
|
+ foo() ?? throw new \Exception();
|
|
|
+ $a = $condition && throw new Exception();
|
|
|
+ $callable = fn () => throw new Exception();
|
|
|
+ $value = $falsableValue ?: throw new InvalidArgumentException();
|
|
|
+}
|
|
|
+
|
|
|
+// https://wiki.php.net/rfc/non-capturing_catches
|
|
|
+// TODO: https://github.com/FriendsOfPHP/PHP-CS-Fixer/pull/5175 - when implementing new rule for fixing such cases, add exception variable in --INPUT-- section
|
|
|
+try {
|
|
|
+ foo();
|
|
|
+} catch (Exception) {
|
|
|
+ // ignore exception
|
|
|
+}
|
|
|
+
|
|
|
+// https://wiki.php.net/rfc/constructor_promotion
|
|
|
+class Point
|
|
|
+{
|
|
|
+ public function __construct(
|
|
|
+ public float $x = 0.0,
|
|
|
+ protected float $y = 0.0,
|
|
|
+ private float $z = 0.0,
|
|
|
+ private ?string $desc = null,
|
|
|
+ ) {
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// https://wiki.php.net/rfc/match_expression_v2
|
|
|
+echo match ($x) {
|
|
|
+ 1, 2 => 'Same for 1 and 2',
|
|
|
+};
|
|
|
+
|
|
|
+// https://wiki.php.net/rfc/add_str_starts_with_and_ends_with_functions
|
|
|
+// no syntax changes
|
|
|
+
|
|
|
+// https://wiki.php.net/rfc/str_contains
|
|
|
+// no syntax changes
|
|
|
+
|
|
|
+// https://wiki.php.net/rfc/deprecate_curly_braces_array_access
|
|
|
+// syntax was deprecated, nothing we can do - a `normalize_index_brace` rule already exists and can be used on PHP <8 (or PHP 8 if errors are ignored)
|
|
|
+
|
|
|
+// https://wiki.php.net/rfc/concatenation_precedence
|
|
|
+// nothing we can do
|
|
|
+
|
|
|
+// https://wiki.php.net/rfc/inheritance_private_methods
|
|
|
+// nothing we can do
|
|
|
+
|
|
|
+// https://wiki.php.net/rfc/ternary_associativity
|
|
|
+// nothing we can do about the warning - a rule can be implemented to run on PHP <8 (or PHP 8 if errors are ignored)
|
|
|
+
|
|
|
+// https://wiki.php.net/rfc/stringable
|
|
|
+// nothing we can do
|
|
|
+
|
|
|
+// Date: mktime() and gmmktime() now require at least one argument. time() can be used to get the current timestamp.
|
|
|
+time();
|
|
|
+time();
|
|
|
+mktime($a);
|
|
|
+gmmktime(1, 2, 3, 4, 5, 6);
|
|
|
+
|
|
|
+// Exif: Removed read_exif_data(). exif_read_data() should be used instead.
|
|
|
+exif_read_data($filename, $sections_needed, $sub_arrays, $read_thumbnail);
|
|
|
+
|
|
|
+// The imap_header() function which is an alias of imap_headerinfo() has been removed.
|
|
|
+imap_headerinfo();
|
|
|
+
|
|
|
+// parse_str() can no longer be used without specifying a result array.
|
|
|
+// nothing we can do
|
|
|
+
|
|
|
+// Calling implode() with parameters in a reverse order ($pieces, $glue) is no longer supported.
|
|
|
+implode('', $pieces);
|
|
|
+implode('', $pieces);
|
|
|
+
|
|
|
+// Mbstring A number of deprecated mbregex aliases have been removed.
|
|
|
+// nothing we can do
|
|
|
+
|
|
|
+// Namespaced names can no longer contain whitespace (nor comments)
|
|
|
+// nothing we can do
|
|
|
+
|
|
|
+--INPUT--
|
|
|
+<?php
|
|
|
+
|
|
|
+// https://wiki.php.net/rfc/named_params
|
|
|
+array_fill(start_index: 0, num: 100, value: 50);
|
|
|
+htmlspecialchars($string, double_encode: false);
|
|
|
+array_slice($array, $offset, $length, preserve_keys: true);
|
|
|
+new ParamNode($name, variadic: $isVariadic, byRef: $passByRef);
|
|
|
+array_foobar(array: $value); // reserved keyword as parameter name!
|
|
|
+
|
|
|
+// https://wiki.php.net/rfc/nullsafe_operator
|
|
|
+$country = $session?->user?->getAddress()?->country;
|
|
|
+
|
|
|
+// https://wiki.php.net/rfc/attributes_v2
|
|
|
+// https://wiki.php.net/rfc/attribute_amendments
|
|
|
+// https://wiki.php.net/rfc/shorter_attribute_syntax
|
|
|
+// https://wiki.php.net/rfc/shorter_attribute_syntax_change
|
|
|
+#[MyAttribute]
|
|
|
+#[\MyExample\MyAttribute]
|
|
|
+#[MyAttribute(1234)]
|
|
|
+#[MyAttribute(value: 1234)]
|
|
|
+#[MyAttribute(MyAttribute::VALUE)]
|
|
|
+#[MyAttribute(array("key" => "value"))]
|
|
|
+#[MyAttribute(100 + 200)]
|
|
|
+#[Attribute(Attribute::TARGET_METHOD | Attribute::TARGET_FUNCTION)]
|
|
|
+#[MyAttribute(1234), MyAttribute(5678)]
|
|
|
+class PostsController
|
|
|
+{
|
|
|
+ #[Route("/api/posts/{id}", methods: ["GET"])]
|
|
|
+ public function get($id): void
|
|
|
+ {
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+$object = new #[ExampleAttribute] class ()
|
|
|
+{
|
|
|
+ #[ExampleAttribute]
|
|
|
+ public function foo(#[ExampleAttribute] $bar): void
|
|
|
+ {
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+// https://wiki.php.net/rfc/union_types_v2
|
|
|
+class Number
|
|
|
+{
|
|
|
+ private int|float|null $number;
|
|
|
+
|
|
|
+ public function setNumber(int|float $number): void
|
|
|
+ {
|
|
|
+ $this->number = $number;
|
|
|
+ }
|
|
|
+
|
|
|
+ public function getNumber(): int|float|null
|
|
|
+ {
|
|
|
+ return $this->number;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// https://wiki.php.net/rfc/class_name_literal_on_object
|
|
|
+// nothing we can do
|
|
|
+
|
|
|
+// https://wiki.php.net/rfc/static_return_type
|
|
|
+class T
|
|
|
+{
|
|
|
+ public function Foo(object $A): ?StatiC
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
+ /** @return static */
|
|
|
+ public function something()
|
|
|
+ {
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// https://wiki.php.net/rfc/variable_syntax_tweaks
|
|
|
+// nothing we can do
|
|
|
+
|
|
|
+// https://wiki.php.net/rfc/trailing_comma_in_parameter_list
|
|
|
+function foo(string $param = null, ) {}
|
|
|
+call_user_func('foo', 1, );
|
|
|
+
|
|
|
+// https://wiki.php.net/rfc/trailing_comma_in_closure_use_list
|
|
|
+$foo1a = function() use ($bar,) {};
|
|
|
+$foo1b = function() use ($bar, ) {};
|
|
|
+$foo2 = function() use ($bar,$baz,) { echo $bar.$baz; };
|
|
|
+
|
|
|
+// https://wiki.php.net/rfc/mixed_type_v2
|
|
|
+class T_Mixed
|
|
|
+{
|
|
|
+ public function Foo(Mixed$a): MIXED
|
|
|
+ {
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// https://wiki.php.net/rfc/throw_expression
|
|
|
+if (1) {
|
|
|
+ foo() ?? throw new \Exception();
|
|
|
+ $a = $condition && throw new Exception();
|
|
|
+ $callable = fn() => throw new Exception();
|
|
|
+ $value = $falsableValue ?: throw new InvalidArgumentException();
|
|
|
+}
|
|
|
+
|
|
|
+// https://wiki.php.net/rfc/non-capturing_catches
|
|
|
+// TODO: https://github.com/FriendsOfPHP/PHP-CS-Fixer/pull/5175 - when implementing new rule for fixing such cases, add exception variable in --INPUT-- section
|
|
|
+try {
|
|
|
+ foo();
|
|
|
+} catch (Exception) {
|
|
|
+ // ignore exception
|
|
|
+}
|
|
|
+
|
|
|
+// https://wiki.php.net/rfc/constructor_promotion
|
|
|
+class Point
|
|
|
+{
|
|
|
+ public function __construct(
|
|
|
+ PUBLIC float $x = 0.0,
|
|
|
+ Protected float $y = 0.0,
|
|
|
+ privatE float $z = 0.0,
|
|
|
+ private ?string $desc = null,
|
|
|
+ ) {
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// https://wiki.php.net/rfc/match_expression_v2
|
|
|
+echo match($x) {
|
|
|
+ 1, 2 => 'Same for 1 and 2',
|
|
|
+};
|
|
|
+
|
|
|
+// https://wiki.php.net/rfc/add_str_starts_with_and_ends_with_functions
|
|
|
+// no syntax changes
|
|
|
+
|
|
|
+// https://wiki.php.net/rfc/str_contains
|
|
|
+// no syntax changes
|
|
|
+
|
|
|
+// https://wiki.php.net/rfc/deprecate_curly_braces_array_access
|
|
|
+// syntax was deprecated, nothing we can do - a `normalize_index_brace` rule already exists and can be used on PHP <8 (or PHP 8 if errors are ignored)
|
|
|
+
|
|
|
+// https://wiki.php.net/rfc/concatenation_precedence
|
|
|
+// nothing we can do
|
|
|
+
|
|
|
+// https://wiki.php.net/rfc/inheritance_private_methods
|
|
|
+// nothing we can do
|
|
|
+
|
|
|
+// https://wiki.php.net/rfc/ternary_associativity
|
|
|
+// nothing we can do about the warning - a rule can be implemented to run on PHP <8 (or PHP 8 if errors are ignored)
|
|
|
+
|
|
|
+// https://wiki.php.net/rfc/stringable
|
|
|
+// nothing we can do
|
|
|
+
|
|
|
+// Date: mktime() and gmmktime() now require at least one argument. time() can be used to get the current timestamp.
|
|
|
+mktime();
|
|
|
+gmmktime();
|
|
|
+mktime($a);
|
|
|
+gmmktime(1, 2, 3, 4, 5, 6);
|
|
|
+
|
|
|
+// Exif: Removed read_exif_data(). exif_read_data() should be used instead.
|
|
|
+read_exif_data($filename, $sections_needed, $sub_arrays, $read_thumbnail);
|
|
|
+
|
|
|
+// The imap_header() function which is an alias of imap_headerinfo() has been removed.
|
|
|
+imap_header();
|
|
|
+
|
|
|
+// parse_str() can no longer be used without specifying a result array.
|
|
|
+// nothing we can do
|
|
|
+
|
|
|
+// Calling implode() with parameters in a reverse order ($pieces, $glue) is no longer supported.
|
|
|
+implode($pieces, '');
|
|
|
+implode($pieces);
|
|
|
+
|
|
|
+// Mbstring A number of deprecated mbregex aliases have been removed.
|
|
|
+// nothing we can do
|
|
|
+
|
|
|
+// Namespaced names can no longer contain whitespace (nor comments)
|
|
|
+// nothing we can do
|