diff --git a/src/Standards/PSR2/Sniffs/Classes/PropertyDeclarationSniff.php b/src/Standards/PSR2/Sniffs/Classes/PropertyDeclarationSniff.php index 8613f34a97..7fe68adf4e 100644 --- a/src/Standards/PSR2/Sniffs/Classes/PropertyDeclarationSniff.php +++ b/src/Standards/PSR2/Sniffs/Classes/PropertyDeclarationSniff.php @@ -44,6 +44,7 @@ protected function processMemberVar(File $phpcsFile, $stackPtr) $find[] = T_VAR; $find[] = T_READONLY; $find[] = T_FINAL; + $find[] = T_ABSTRACT; $find[] = T_SEMICOLON; $find[] = T_OPEN_CURLY_BRACKET; @@ -195,6 +196,31 @@ protected function processMemberVar(File $phpcsFile, $stackPtr) } }//end if + if ($hasVisibilityModifier === true && $propertyInfo['is_abstract'] === true) { + $scopePtr = $firstVisibilityModifier; + $abstractPtr = $phpcsFile->findPrevious(T_ABSTRACT, ($stackPtr - 1)); + if ($abstractPtr > $scopePtr) { + $error = 'The abstract declaration must come before the visibility declaration'; + $fix = $phpcsFile->addFixableError($error, $stackPtr, 'AbstractAfterVisibility'); + if ($fix === true) { + $phpcsFile->fixer->beginChangeset(); + + for ($i = ($abstractPtr + 1); $abstractPtr < $stackPtr; $i++) { + if ($tokens[$i]['code'] !== T_WHITESPACE) { + break; + } + + $phpcsFile->fixer->replaceToken($i, ''); + } + + $phpcsFile->fixer->replaceToken($abstractPtr, ''); + $phpcsFile->fixer->addContentBefore($scopePtr, $tokens[$abstractPtr]['content'].' '); + + $phpcsFile->fixer->endChangeset(); + } + } + }//end if + if ($hasVisibilityModifier === true && $propertyInfo['is_static'] === true) { $scopePtr = $lastVisibilityModifier; $staticPtr = $phpcsFile->findPrevious(T_STATIC, ($stackPtr - 1)); diff --git a/src/Standards/PSR2/Tests/Classes/PropertyDeclarationUnitTest.inc b/src/Standards/PSR2/Tests/Classes/PropertyDeclarationUnitTest.inc index 2e1785a204..15b1bbc0c5 100644 --- a/src/Standards/PSR2/Tests/Classes/PropertyDeclarationUnitTest.inc +++ b/src/Standards/PSR2/Tests/Classes/PropertyDeclarationUnitTest.inc @@ -126,3 +126,11 @@ class AsymmetricVisibility { final static protected(set) bool $wrongOrder12; static public(set) final bool $wrongOrder13; } + +abstract class AbstractProperties { + abstract public int $foo { get; } + abstract protected (D|N)|false $foo { set; } + abstract array $foo { get; } + public ABSTRACT ?int $wrongOrder1 { set; } + protected abstract ?string $wrongOrder2 { get; } +} diff --git a/src/Standards/PSR2/Tests/Classes/PropertyDeclarationUnitTest.inc.fixed b/src/Standards/PSR2/Tests/Classes/PropertyDeclarationUnitTest.inc.fixed index b398e2fe78..a2ffb05275 100644 --- a/src/Standards/PSR2/Tests/Classes/PropertyDeclarationUnitTest.inc.fixed +++ b/src/Standards/PSR2/Tests/Classes/PropertyDeclarationUnitTest.inc.fixed @@ -123,3 +123,11 @@ class AsymmetricVisibility { final protected(set) static bool $wrongOrder12; final public(set) static bool $wrongOrder13; } + +abstract class AbstractProperties { + abstract public int $foo { get; } + abstract protected (D|N)|false $foo { set; } + abstract array $foo { get; } + ABSTRACT public ?int $wrongOrder1 { set; } + abstract protected ?string $wrongOrder2 { get; } +} diff --git a/src/Standards/PSR2/Tests/Classes/PropertyDeclarationUnitTest.php b/src/Standards/PSR2/Tests/Classes/PropertyDeclarationUnitTest.php index bce3d9f1df..7d0160fdaf 100644 --- a/src/Standards/PSR2/Tests/Classes/PropertyDeclarationUnitTest.php +++ b/src/Standards/PSR2/Tests/Classes/PropertyDeclarationUnitTest.php @@ -76,6 +76,10 @@ public function getErrorList() 125 => 1, 126 => 1, 127 => 2, + 132 => 1, + 133 => 1, + 134 => 1, + 135 => 1, ]; }//end getErrorList()