Skip to content

Commit 76b6af9

Browse files
authored
Merge pull request #677 from PHPCSStandards/php-8.4/bcfile-support-asym-visibility
Sync with upstream / PHP 8.4 asym visibility support
2 parents ff83d52 + f438f28 commit 76b6af9

File tree

8 files changed

+549
-75
lines changed

8 files changed

+549
-75
lines changed

PHPCSUtils/BackCompat/BCFile.php

Lines changed: 74 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,12 @@ public static function getDeclarationName(File $phpcsFile, $stackPtr)
185185
* // This index will only be set if the property is readonly.
186186
* ```
187187
*
188+
* ... and if the promoted property uses asymmetric visibility, these additional array indexes will also be available:
189+
* ```php
190+
* 'set_visibility' => string, // The property set-visibility as declared.
191+
* 'set_visibility_token' => integer, // The stack pointer to the set-visibility modifier token.
192+
* ```
193+
*
188194
* PHPCS cross-version compatible version of the `File::getMethodParameters()` method.
189195
*
190196
* Changelog for the PHPCS native function:
@@ -196,6 +202,7 @@ public static function getDeclarationName(File $phpcsFile, $stackPtr)
196202
*
197203
* @since 1.0.0
198204
* @since 1.0.6 Sync with PHPCS 3.8.0, support for readonly properties without explicit visibility. PHPCS#3801.
205+
* @since 1.1.0 Sync with PHPCS 3.13.1, support for asymmetric properties. PHPCS(new)#851
199206
*
200207
* @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.
201208
* @param int $stackPtr The position in the stack of the function token
@@ -242,23 +249,24 @@ public static function getMethodParameters(File $phpcsFile, $stackPtr)
242249

243250
$closer = $tokens[$opener]['parenthesis_closer'];
244251

245-
$vars = [];
246-
$currVar = null;
247-
$paramStart = ($opener + 1);
248-
$defaultStart = null;
249-
$equalToken = null;
250-
$paramCount = 0;
251-
$hasAttributes = false;
252-
$passByReference = false;
253-
$referenceToken = false;
254-
$variableLength = false;
255-
$variadicToken = false;
256-
$typeHint = '';
257-
$typeHintToken = false;
258-
$typeHintEndToken = false;
259-
$nullableType = false;
260-
$visibilityToken = null;
261-
$readonlyToken = null;
252+
$vars = [];
253+
$currVar = null;
254+
$paramStart = ($opener + 1);
255+
$defaultStart = null;
256+
$equalToken = null;
257+
$paramCount = 0;
258+
$hasAttributes = false;
259+
$passByReference = false;
260+
$referenceToken = false;
261+
$variableLength = false;
262+
$variadicToken = false;
263+
$typeHint = '';
264+
$typeHintToken = false;
265+
$typeHintEndToken = false;
266+
$nullableType = false;
267+
$visibilityToken = null;
268+
$setVisibilityToken = null;
269+
$readonlyToken = null;
262270

263271
for ($i = $paramStart; $i <= $closer; $i++) {
264272
// Check to see if this token has a parenthesis or bracket opener. If it does
@@ -392,6 +400,13 @@ public static function getMethodParameters(File $phpcsFile, $stackPtr)
392400
$visibilityToken = $i;
393401
}
394402
break;
403+
case T_PUBLIC_SET:
404+
case T_PROTECTED_SET:
405+
case T_PRIVATE_SET:
406+
if ($defaultStart === null) {
407+
$setVisibilityToken = $i;
408+
}
409+
break;
395410
case T_READONLY:
396411
if ($defaultStart === null) {
397412
$readonlyToken = $i;
@@ -426,16 +441,21 @@ public static function getMethodParameters(File $phpcsFile, $stackPtr)
426441
$vars[$paramCount]['type_hint_end_token'] = $typeHintEndToken;
427442
$vars[$paramCount]['nullable_type'] = $nullableType;
428443

429-
if ($visibilityToken !== null || $readonlyToken !== null) {
444+
if ($visibilityToken !== null || $setVisibilityToken !== null || $readonlyToken !== null) {
430445
$vars[$paramCount]['property_visibility'] = 'public';
431446
$vars[$paramCount]['visibility_token'] = false;
432-
$vars[$paramCount]['property_readonly'] = false;
433447

434448
if ($visibilityToken !== null) {
435449
$vars[$paramCount]['property_visibility'] = $tokens[$visibilityToken]['content'];
436450
$vars[$paramCount]['visibility_token'] = $visibilityToken;
437451
}
438452

453+
if ($setVisibilityToken !== null) {
454+
$vars[$paramCount]['set_visibility'] = $tokens[$setVisibilityToken]['content'];
455+
$vars[$paramCount]['set_visibility_token'] = $setVisibilityToken;
456+
}
457+
458+
$vars[$paramCount]['property_readonly'] = false;
439459
if ($readonlyToken !== null) {
440460
$vars[$paramCount]['property_readonly'] = true;
441461
$vars[$paramCount]['readonly_token'] = $readonlyToken;
@@ -449,21 +469,22 @@ public static function getMethodParameters(File $phpcsFile, $stackPtr)
449469
}
450470

451471
// Reset the vars, as we are about to process the next parameter.
452-
$currVar = null;
453-
$paramStart = ($i + 1);
454-
$defaultStart = null;
455-
$equalToken = null;
456-
$hasAttributes = false;
457-
$passByReference = false;
458-
$referenceToken = false;
459-
$variableLength = false;
460-
$variadicToken = false;
461-
$typeHint = '';
462-
$typeHintToken = false;
463-
$typeHintEndToken = false;
464-
$nullableType = false;
465-
$visibilityToken = null;
466-
$readonlyToken = null;
472+
$currVar = null;
473+
$paramStart = ($i + 1);
474+
$defaultStart = null;
475+
$equalToken = null;
476+
$hasAttributes = false;
477+
$passByReference = false;
478+
$referenceToken = false;
479+
$variableLength = false;
480+
$variadicToken = false;
481+
$typeHint = '';
482+
$typeHintToken = false;
483+
$typeHintEndToken = false;
484+
$nullableType = false;
485+
$visibilityToken = null;
486+
$setVisibilityToken = null;
487+
$readonlyToken = null;
467488

468489
++$paramCount;
469490
break;
@@ -532,6 +553,9 @@ public static function getMethodProperties(File $phpcsFile, $stackPtr)
532553
* array(
533554
* 'scope' => string, // Public, private, or protected.
534555
* 'scope_specified' => boolean, // TRUE if the scope was explicitly specified.
556+
* 'set_scope' => string|false, // Scope for asymmetric visibility.
557+
* // Either public, private, or protected or
558+
* // FALSE if no set scope is specified.
535559
* 'is_static' => boolean, // TRUE if the static keyword was found.
536560
* 'is_readonly' => boolean, // TRUE if the readonly keyword was found.
537561
* 'is_final' => boolean, // TRUE if the final keyword was found.
@@ -598,19 +622,18 @@ public static function getMemberProperties(File $phpcsFile, $stackPtr)
598622
}
599623

600624
$valid = [
601-
T_PUBLIC => T_PUBLIC,
602-
T_PRIVATE => T_PRIVATE,
603-
T_PROTECTED => T_PROTECTED,
604-
T_STATIC => T_STATIC,
605-
T_VAR => T_VAR,
606-
T_READONLY => T_READONLY,
607-
T_FINAL => T_FINAL,
625+
T_STATIC => T_STATIC,
626+
T_VAR => T_VAR,
627+
T_READONLY => T_READONLY,
628+
T_FINAL => T_FINAL,
608629
];
609630

631+
$valid += Tokens::$scopeModifiers;
610632
$valid += Tokens::$emptyTokens;
611633

612634
$scope = 'public';
613635
$scopeSpecified = false;
636+
$setScope = false;
614637
$isStatic = false;
615638
$isReadonly = false;
616639
$isFinal = false;
@@ -643,6 +666,15 @@ public static function getMemberProperties(File $phpcsFile, $stackPtr)
643666
$scope = 'protected';
644667
$scopeSpecified = true;
645668
break;
669+
case T_PUBLIC_SET:
670+
$setScope = 'public';
671+
break;
672+
case T_PROTECTED_SET:
673+
$setScope = 'protected';
674+
break;
675+
case T_PRIVATE_SET:
676+
$setScope = 'private';
677+
break;
646678
case T_STATIC:
647679
$isStatic = true;
648680
break;
@@ -692,6 +724,7 @@ public static function getMemberProperties(File $phpcsFile, $stackPtr)
692724
return [
693725
'scope' => $scope,
694726
'scope_specified' => $scopeSpecified,
727+
'set_scope' => $setScope,
695728
'is_static' => $isStatic,
696729
'is_readonly' => $isReadonly,
697730
'is_final' => $isFinal,

PHPCSUtils/Utils/FunctionDeclarations.php

Lines changed: 53 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,12 @@ public static function getProperties(File $phpcsFile, $stackPtr)
384384
* // This index will only be set if the property is readonly.
385385
* ```
386386
*
387+
* ... and if the promoted property uses asymmetric visibility, these additional array indexes will also be available:
388+
* ```php
389+
* 'set_visibility' => string, // The property set-visibility as declared.
390+
* 'set_visibility_token' => int, // The stack pointer to the set-visibility modifier token.
391+
* ```
392+
*
387393
* Main differences with the PHPCS version:
388394
* - Defensive coding against incorrect calls to this method.
389395
* - More efficient and more stable checking whether a `T_USE` token is a closure use.
@@ -457,23 +463,24 @@ public static function getParameters(File $phpcsFile, $stackPtr)
457463

458464
$closer = $tokens[$opener]['parenthesis_closer'];
459465

460-
$vars = [];
461-
$currVar = null;
462-
$paramStart = ($opener + 1);
463-
$defaultStart = null;
464-
$equalToken = null;
465-
$paramCount = 0;
466-
$hasAttributes = false;
467-
$passByReference = false;
468-
$referenceToken = false;
469-
$variableLength = false;
470-
$variadicToken = false;
471-
$typeHint = '';
472-
$typeHintToken = false;
473-
$typeHintEndToken = false;
474-
$nullableType = false;
475-
$visibilityToken = null;
476-
$readonlyToken = null;
466+
$vars = [];
467+
$currVar = null;
468+
$paramStart = ($opener + 1);
469+
$defaultStart = null;
470+
$equalToken = null;
471+
$paramCount = 0;
472+
$hasAttributes = false;
473+
$passByReference = false;
474+
$referenceToken = false;
475+
$variableLength = false;
476+
$variadicToken = false;
477+
$typeHint = '';
478+
$typeHintToken = false;
479+
$typeHintEndToken = false;
480+
$nullableType = false;
481+
$visibilityToken = null;
482+
$setVisibilityToken = null;
483+
$readonlyToken = null;
477484

478485
$parameterTypeTokens = Collections::parameterTypeTokens();
479486

@@ -529,6 +536,12 @@ public static function getParameters(File $phpcsFile, $stackPtr)
529536
$visibilityToken = $i;
530537
break;
531538

539+
case \T_PUBLIC_SET:
540+
case \T_PROTECTED_SET:
541+
case \T_PRIVATE_SET:
542+
$setVisibilityToken = $i;
543+
break;
544+
532545
case \T_READONLY:
533546
$readonlyToken = $i;
534547
break;
@@ -566,16 +579,21 @@ public static function getParameters(File $phpcsFile, $stackPtr)
566579
$vars[$paramCount]['type_hint_end_token'] = $typeHintEndToken;
567580
$vars[$paramCount]['nullable_type'] = $nullableType;
568581

569-
if ($visibilityToken !== null || $readonlyToken !== null) {
582+
if ($visibilityToken !== null || $setVisibilityToken !== null || $readonlyToken !== null) {
570583
$vars[$paramCount]['property_visibility'] = 'public';
571584
$vars[$paramCount]['visibility_token'] = false;
572-
$vars[$paramCount]['property_readonly'] = false;
573585

574586
if ($visibilityToken !== null) {
575587
$vars[$paramCount]['property_visibility'] = $tokens[$visibilityToken]['content'];
576588
$vars[$paramCount]['visibility_token'] = $visibilityToken;
577589
}
578590

591+
if ($setVisibilityToken !== null) {
592+
$vars[$paramCount]['set_visibility'] = $tokens[$setVisibilityToken]['content'];
593+
$vars[$paramCount]['set_visibility_token'] = $setVisibilityToken;
594+
}
595+
596+
$vars[$paramCount]['property_readonly'] = false;
579597
if ($readonlyToken !== null) {
580598
$vars[$paramCount]['property_readonly'] = true;
581599
$vars[$paramCount]['readonly_token'] = $readonlyToken;
@@ -589,21 +607,22 @@ public static function getParameters(File $phpcsFile, $stackPtr)
589607
}
590608

591609
// Reset the vars, as we are about to process the next parameter.
592-
$currVar = null;
593-
$paramStart = ($i + 1);
594-
$defaultStart = null;
595-
$equalToken = null;
596-
$hasAttributes = false;
597-
$passByReference = false;
598-
$referenceToken = false;
599-
$variableLength = false;
600-
$variadicToken = false;
601-
$typeHint = '';
602-
$typeHintToken = false;
603-
$typeHintEndToken = false;
604-
$nullableType = false;
605-
$visibilityToken = null;
606-
$readonlyToken = null;
610+
$currVar = null;
611+
$paramStart = ($i + 1);
612+
$defaultStart = null;
613+
$equalToken = null;
614+
$hasAttributes = false;
615+
$passByReference = false;
616+
$referenceToken = false;
617+
$variableLength = false;
618+
$variadicToken = false;
619+
$typeHint = '';
620+
$typeHintToken = false;
621+
$typeHintEndToken = false;
622+
$nullableType = false;
623+
$visibilityToken = null;
624+
$setVisibilityToken = null;
625+
$readonlyToken = null;
607626

608627
++$paramCount;
609628
break;

PHPCSUtils/Utils/Variables.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ final class Variables
102102
* array(
103103
* 'scope' => string, // Public, private, or protected.
104104
* 'scope_specified' => boolean, // TRUE if the scope was explicitly specified.
105+
* 'set_scope' => string|false, // Scope for asymmetric visibility.
106+
* // Either public, private, or protected or
107+
* // FALSE if no set scope is specified.
105108
* 'is_static' => boolean, // TRUE if the static keyword was found.
106109
* 'is_readonly' => boolean, // TRUE if the readonly keyword was found.
107110
* 'is_final' => boolean, // TRUE if the final keyword was found.
@@ -148,6 +151,7 @@ public static function getMemberProperties(File $phpcsFile, $stackPtr)
148151

149152
$scope = 'public';
150153
$scopeSpecified = false;
154+
$setScope = false;
151155
$isStatic = false;
152156
$isReadonly = false;
153157
$isFinal = false;
@@ -180,6 +184,24 @@ public static function getMemberProperties(File $phpcsFile, $stackPtr)
180184
$scope = 'protected';
181185
$scopeSpecified = true;
182186
break;
187+
case \T_PUBLIC_SET:
188+
$setScope = 'public';
189+
if ($scopeSpecified === false) {
190+
$scope = 'public';
191+
}
192+
break;
193+
case \T_PROTECTED_SET:
194+
$setScope = 'protected';
195+
if ($scopeSpecified === false) {
196+
$scope = 'public';
197+
}
198+
break;
199+
case \T_PRIVATE_SET:
200+
$setScope = 'private';
201+
if ($scopeSpecified === false) {
202+
$scope = 'public';
203+
}
204+
break;
183205
case \T_STATIC:
184206
$isStatic = true;
185207
break;
@@ -228,6 +250,7 @@ public static function getMemberProperties(File $phpcsFile, $stackPtr)
228250
$returnValue = [
229251
'scope' => $scope,
230252
'scope_specified' => $scopeSpecified,
253+
'set_scope' => $setScope,
231254
'is_static' => $isStatic,
232255
'is_readonly' => $isReadonly,
233256
'is_final' => $isFinal,

0 commit comments

Comments
 (0)