Skip to content

Commit 6b0c204

Browse files
authored
Merge pull request #458 from PHPCSStandards/develop
Release 1.0.4
2 parents 73d7b07 + 5070cee commit 6b0c204

File tree

6 files changed

+170
-87
lines changed

6 files changed

+170
-87
lines changed

CHANGELOG.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,23 @@ This projects adheres to [Keep a CHANGELOG](https://keepachangelog.com/) and use
99

1010
_Nothing yet._
1111

12+
## [1.0.4] - 2023-04-15
13+
14+
### Changed
15+
16+
#### Other
17+
18+
* Minor documentation improvements.
19+
20+
### Fixed
21+
22+
#### Utils
23+
24+
* The `FunctionDeclarations::getParameters()` method will now correctly handle constructor promoted properties with `readonly`, but without explicit visibility set. [#456]
25+
26+
[#456]: https://github.com/PHPCSStandards/PHPCSUtils/pull/456
27+
28+
1229
## [1.0.3] - 2023-04-13
1330

1431
### Changed
@@ -822,6 +839,7 @@ This initial alpha release contains the following utility classes:
822839

823840

824841
[Unreleased]: https://github.com/PHPCSStandards/PHPCSUtils/compare/stable...HEAD
842+
[1.0.4]: https://github.com/PHPCSStandards/PHPCSUtils/compare/1.0.3...1.0.4
825843
[1.0.3]: https://github.com/PHPCSStandards/PHPCSUtils/compare/1.0.2...1.0.3
826844
[1.0.2]: https://github.com/PHPCSStandards/PHPCSUtils/compare/1.0.1...1.0.2
827845
[1.0.1]: https://github.com/PHPCSStandards/PHPCSUtils/compare/1.0.0...1.0.1

PHPCSUtils/BackCompat/BCFile.php

Lines changed: 46 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -107,25 +107,25 @@ public static function getDeclarationName(File $phpcsFile, $stackPtr)
107107
* Each parameter is in the following format:
108108
* ```php
109109
* 0 => array(
110-
* 'name' => '$var', // The variable name.
111-
* 'token' => integer, // The stack pointer to the variable name.
112-
* 'content' => string, // The full content of the variable definition.
113-
* 'has_attributes' => boolean, // Does the parameter have one or more attributes attached ?
114-
* 'pass_by_reference' => boolean, // Is the variable passed by reference?
115-
* 'reference_token' => integer, // The stack pointer to the reference operator
116-
* // or FALSE if the param is not passed by reference.
117-
* 'variable_length' => boolean, // Is the param of variable length through use of `...` ?
118-
* 'variadic_token' => integer, // The stack pointer to the ... operator
119-
* // or FALSE if the param is not variable length.
120-
* 'type_hint' => string, // The type hint for the variable.
121-
* 'type_hint_token' => integer, // The stack pointer to the start of the type hint
122-
* // or FALSE if there is no type hint.
123-
* 'type_hint_end_token' => integer, // The stack pointer to the end of the type hint
124-
* // or FALSE if there is no type hint.
125-
* 'nullable_type' => boolean, // TRUE if the var type is preceded by the nullability
126-
* // operator.
127-
* 'comma_token' => integer, // The stack pointer to the comma after the param
128-
* // or FALSE if this is the last param.
110+
* 'name' => string, // The variable name.
111+
* 'token' => integer, // The stack pointer to the variable name.
112+
* 'content' => string, // The full content of the variable definition.
113+
* 'has_attributes' => boolean, // Does the parameter have one or more attributes attached ?
114+
* 'pass_by_reference' => boolean, // Is the variable passed by reference?
115+
* 'reference_token' => integer|false, // The stack pointer to the reference operator
116+
* // or FALSE if the param is not passed by reference.
117+
* 'variable_length' => boolean, // Is the param of variable length through use of `...` ?
118+
* 'variadic_token' => integer|false, // The stack pointer to the ... operator
119+
* // or FALSE if the param is not variable length.
120+
* 'type_hint' => string, // The type hint for the variable.
121+
* 'type_hint_token' => integer|false, // The stack pointer to the start of the type hint
122+
* // or FALSE if there is no type hint.
123+
* 'type_hint_end_token' => integer|false, // The stack pointer to the end of the type hint
124+
* // or FALSE if there is no type hint.
125+
* 'nullable_type' => boolean, // TRUE if the var type is preceded by the nullability
126+
* // operator.
127+
* 'comma_token' => integer|false, // The stack pointer to the comma after the param
128+
* // or FALSE if this is the last param.
129129
* )
130130
* ```
131131
*
@@ -142,6 +142,7 @@ public static function getDeclarationName(File $phpcsFile, $stackPtr)
142142
* 'visibility_token' => integer, // The stack pointer to the visibility modifier token.
143143
* 'property_readonly' => bool, // TRUE if the readonly keyword was found.
144144
* 'readonly_token' => integer, // The stack pointer to the readonly modifier token.
145+
* // This index will only be set if the property is readonly.
145146
* ```
146147
*
147148
* PHPCS cross-version compatible version of the `File::getMethodParameters()` method.
@@ -431,19 +432,19 @@ public static function getMethodParameters(File $phpcsFile, $stackPtr)
431432
* The format of the return value is:
432433
* ```php
433434
* array(
434-
* 'scope' => 'public', // Public, private, or protected
435-
* 'scope_specified' => true, // TRUE if the scope keyword was found.
436-
* 'return_type' => '', // The return type of the method.
437-
* 'return_type_token' => integer, // The stack pointer to the start of the return type
438-
* // or FALSE if there is no return type.
439-
* 'return_type_end_token' => integer, // The stack pointer to the end of the return type
440-
* // or FALSE if there is no return type.
441-
* 'nullable_return_type' => false, // TRUE if the return type is preceded by
442-
* // the nullability operator.
443-
* 'is_abstract' => false, // TRUE if the abstract keyword was found.
444-
* 'is_final' => false, // TRUE if the final keyword was found.
445-
* 'is_static' => false, // TRUE if the static keyword was found.
446-
* 'has_body' => false, // TRUE if the method has a body
435+
* 'scope' => string, // Public, private, or protected
436+
* 'scope_specified' => boolean, // TRUE if the scope keyword was found.
437+
* 'return_type' => string, // The return type of the method.
438+
* 'return_type_token' => integer|false, // The stack pointer to the start of the return type
439+
* // or FALSE if there is no return type.
440+
* 'return_type_end_token' => integer|false, // The stack pointer to the end of the return type
441+
* // or FALSE if there is no return type.
442+
* 'nullable_return_type' => boolean, // TRUE if the return type is preceded by
443+
* // the nullability operator.
444+
* 'is_abstract' => boolean, // TRUE if the abstract keyword was found.
445+
* 'is_final' => boolean, // TRUE if the final keyword was found.
446+
* 'is_static' => boolean, // TRUE if the static keyword was found.
447+
* 'has_body' => boolean, // TRUE if the method has a body
447448
* );
448449
* ```
449450
*
@@ -478,17 +479,17 @@ public static function getMethodProperties(File $phpcsFile, $stackPtr)
478479
* The format of the return value is:
479480
* ```php
480481
* array(
481-
* 'scope' => string, // Public, private, or protected.
482-
* 'scope_specified' => boolean, // TRUE if the scope was explicitly specified.
483-
* 'is_static' => boolean, // TRUE if the static keyword was found.
484-
* 'is_readonly' => boolean, // TRUE if the readonly keyword was found.
485-
* 'type' => string, // The type of the var (empty if no type specified).
486-
* 'type_token' => integer, // The stack pointer to the start of the type
487-
* // or FALSE if there is no type.
488-
* 'type_end_token' => integer, // The stack pointer to the end of the type
489-
* // or FALSE if there is no type.
490-
* 'nullable_type' => boolean, // TRUE if the type is preceded by the
491-
* // nullability operator.
482+
* 'scope' => string, // Public, private, or protected.
483+
* 'scope_specified' => boolean, // TRUE if the scope was explicitly specified.
484+
* 'is_static' => boolean, // TRUE if the static keyword was found.
485+
* 'is_readonly' => boolean, // TRUE if the readonly keyword was found.
486+
* 'type' => string, // The type of the var (empty if no type specified).
487+
* 'type_token' => integer|false, // The stack pointer to the start of the type
488+
* // or FALSE if there is no type.
489+
* 'type_end_token' => integer|false, // The stack pointer to the end of the type
490+
* // or FALSE if there is no type.
491+
* 'nullable_type' => boolean, // TRUE if the type is preceded by the
492+
* // nullability operator.
492493
* );
493494
* ```
494495
*
@@ -524,8 +525,8 @@ public static function getMemberProperties(File $phpcsFile, $stackPtr)
524525
* The format of the return value is:
525526
* ```php
526527
* array(
527-
* 'is_abstract' => false, // TRUE if the abstract keyword was found.
528-
* 'is_final' => false, // TRUE if the final keyword was found.
528+
* 'is_abstract' => boolean, // TRUE if the abstract keyword was found.
529+
* 'is_final' => boolean, // TRUE if the final keyword was found.
529530
* );
530531
* ```
531532
*

PHPCSUtils/Utils/FunctionDeclarations.php

Lines changed: 38 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ public static function getName(File $phpcsFile, $stackPtr)
148148
* - Defensive coding against incorrect calls to this method.
149149
* - More efficient checking whether a function has a body.
150150
* - Support for PHP 8.0 identifier name tokens in return types, cross-version PHP & PHPCS.
151+
* - Support for constructor property promotion with the PHP 8.1 readonly keyword without explicit visibility.
151152
* - Support for the PHP 8.2 `true` type.
152153
*
153154
* @see \PHP_CodeSniffer\Files\File::getMethodProperties() Original source.
@@ -314,25 +315,25 @@ public static function getProperties(File $phpcsFile, $stackPtr)
314315
*
315316
* ```php
316317
* 0 => array(
317-
* 'name' => string, // The variable name.
318-
* 'token' => int, // The stack pointer to the variable name.
319-
* 'content' => string, // The full content of the variable definition.
320-
* 'has_attributes' => bool, // Does the parameter have one or more attributes attached ?
321-
* 'pass_by_reference' => bool, // Is the variable passed by reference?
322-
* 'reference_token' => int, // The stack pointer to the reference operator
323-
* // or FALSE if the param is not passed by reference.
324-
* 'variable_length' => bool, // Is the param of variable length through use of `...` ?
325-
* 'variadic_token' => int, // The stack pointer to the ... operator
326-
* // or FALSE if the param is not variable length.
327-
* 'type_hint' => string, // The type hint for the variable.
328-
* 'type_hint_token' => int, // The stack pointer to the start of the type hint
329-
* // or FALSE if there is no type hint.
330-
* 'type_hint_end_token' => int, // The stack pointer to the end of the type hint
331-
* // or FALSE if there is no type hint.
332-
* 'nullable_type' => bool, // TRUE if the var type is preceded by the nullability
333-
* // operator.
334-
* 'comma_token' => int, // The stack pointer to the comma after the param
335-
* // or FALSE if this is the last param.
318+
* 'name' => string, // The variable name.
319+
* 'token' => int, // The stack pointer to the variable name.
320+
* 'content' => string, // The full content of the variable definition.
321+
* 'has_attributes' => bool, // Does the parameter have one or more attributes attached ?
322+
* 'pass_by_reference' => bool, // Is the variable passed by reference?
323+
* 'reference_token' => int|false, // The stack pointer to the reference operator
324+
* // or FALSE if the param is not passed by reference.
325+
* 'variable_length' => bool, // Is the param of variable length through use of `...` ?
326+
* 'variadic_token' => int|false, // The stack pointer to the ... operator
327+
* // or FALSE if the param is not variable length.
328+
* 'type_hint' => string, // The type hint for the variable.
329+
* 'type_hint_token' => int|false, // The stack pointer to the start of the type hint
330+
* // or FALSE if there is no type hint.
331+
* 'type_hint_end_token' => int|false, // The stack pointer to the end of the type hint
332+
* // or FALSE if there is no type hint.
333+
* 'nullable_type' => bool, // TRUE if the var type is preceded by the nullability
334+
* // operator.
335+
* 'comma_token' => int|false, // The stack pointer to the comma after the param
336+
* // or FALSE if this is the last param.
336337
* )
337338
* ```
338339
*
@@ -345,10 +346,12 @@ public static function getProperties(File $phpcsFile, $stackPtr)
345346
*
346347
* Parameters declared using PHP 8 constructor property promotion, have these additional array indexes:
347348
* ```php
348-
* 'property_visibility' => string, // The property visibility as declared.
349-
* 'visibility_token' => int, // The stack pointer to the visibility modifier token.
350-
* 'property_readonly' => bool, // TRUE if the readonly keyword was found.
351-
* 'readonly_token' => int, // The stack pointer to the readonly modifier token.
349+
* 'property_visibility' => string, // The property visibility as declared.
350+
* 'visibility_token' => int|false, // The stack pointer to the visibility modifier token.
351+
* // or FALSE if the visibility is not explicitly declared.
352+
* 'property_readonly' => bool, // TRUE if the readonly keyword was found.
353+
* 'readonly_token' => int, // The stack pointer to the readonly modifier token.
354+
* // This index will only be set if the property is readonly.
352355
* ```
353356
*
354357
* Main differences with the PHPCS version:
@@ -532,15 +535,20 @@ public static function getParameters(File $phpcsFile, $stackPtr)
532535
$vars[$paramCount]['type_hint_end_token'] = $typeHintEndToken;
533536
$vars[$paramCount]['nullable_type'] = $nullableType;
534537

535-
if ($visibilityToken !== null) {
536-
$vars[$paramCount]['property_visibility'] = $tokens[$visibilityToken]['content'];
537-
$vars[$paramCount]['visibility_token'] = $visibilityToken;
538+
if ($visibilityToken !== null || $readonlyToken !== null) {
539+
$vars[$paramCount]['property_visibility'] = 'public';
540+
$vars[$paramCount]['visibility_token'] = false;
538541
$vars[$paramCount]['property_readonly'] = false;
539-
}
540542

541-
if ($readonlyToken !== null) {
542-
$vars[$paramCount]['property_readonly'] = true;
543-
$vars[$paramCount]['readonly_token'] = $readonlyToken;
543+
if ($visibilityToken !== null) {
544+
$vars[$paramCount]['property_visibility'] = $tokens[$visibilityToken]['content'];
545+
$vars[$paramCount]['visibility_token'] = $visibilityToken;
546+
}
547+
548+
if ($readonlyToken !== null) {
549+
$vars[$paramCount]['property_readonly'] = true;
550+
$vars[$paramCount]['readonly_token'] = $readonlyToken;
551+
}
544552
}
545553

546554
if ($tokens[$i]['code'] === \T_COMMA) {

PHPCSUtils/Utils/Variables.php

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -96,17 +96,17 @@ final class Variables
9696
* The format of the return value is:
9797
* ```php
9898
* array(
99-
* 'scope' => string, // Public, private, or protected.
100-
* 'scope_specified' => boolean, // TRUE if the scope was explicitly specified.
101-
* 'is_static' => boolean, // TRUE if the static keyword was found.
102-
* 'is_readonly' => boolean, // TRUE if the readonly keyword was found.
103-
* 'type' => string, // The type of the var (empty if no type specified).
104-
* 'type_token' => integer, // The stack pointer to the start of the type
105-
* // or FALSE if there is no type.
106-
* 'type_end_token' => integer, // The stack pointer to the end of the type
107-
* // or FALSE if there is no type.
108-
* 'nullable_type' => boolean, // TRUE if the type is preceded by the
109-
* // nullability operator.
99+
* 'scope' => string, // Public, private, or protected.
100+
* 'scope_specified' => boolean, // TRUE if the scope was explicitly specified.
101+
* 'is_static' => boolean, // TRUE if the static keyword was found.
102+
* 'is_readonly' => boolean, // TRUE if the readonly keyword was found.
103+
* 'type' => string, // The type of the var (empty if no type specified).
104+
* 'type_token' => integer|false, // The stack pointer to the start of the type
105+
* // or FALSE if there is no type.
106+
* 'type_end_token' => integer|false, // The stack pointer to the end of the type
107+
* // or FALSE if there is no type.
108+
* 'nullable_type' => boolean, // TRUE if the type is preceded by the
109+
* // nullability operator.
110110
* );
111111
* ```
112112
*

Tests/Utils/FunctionDeclarations/GetParametersDiffTest.inc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,8 @@ function pseudoTypeTrue(?true $var = true) {}
66
/* testPHP82PseudoTypeFalseAndTrue */
77
// Intentional fatal error - Type contains both true and false, bool should be used instead, but that's not the concern of the method.
88
function pseudoTypeFalseAndTrue(true|false $var = true) {}
9+
10+
class ConstructorPropertyPromotionWithOnlyReadOnly {
11+
/* testPHP81ConstructorPropertyPromotionWithOnlyReadOnly */
12+
public function __construct(readonly Foo&Bar $promotedProp, readonly ?bool $promotedToo,) {}
13+
}

0 commit comments

Comments
 (0)