SpacePossum 3 лет назад
Родитель
Сommit
85355e715d

+ 1 - 1
src/Fixer/ClassNotation/ClassAttributesSeparationFixer.php

@@ -499,7 +499,7 @@ class Sample
 
     private function getFirstTokenIndexOfClassElement(Tokens $tokens, array $class, array $element): int
     {
-        $modifierTypes = [T_PRIVATE, T_PROTECTED, T_PUBLIC, T_ABSTRACT, T_FINAL, T_STATIC, T_STRING, T_NS_SEPARATOR, T_VAR, CT::T_NULLABLE_TYPE, CT::T_ARRAY_TYPEHINT, CT::T_TYPE_ALTERNATION];
+        $modifierTypes = [T_PRIVATE, T_PROTECTED, T_PUBLIC, T_ABSTRACT, T_FINAL, T_STATIC, T_STRING, T_NS_SEPARATOR, T_VAR, CT::T_NULLABLE_TYPE, CT::T_ARRAY_TYPEHINT, CT::T_TYPE_ALTERNATION, CT::T_TYPE_INTERSECTION];
 
         if (\defined('T_READONLY')) { // @TODO: drop condition when PHP 8.1+ is required
             $modifierTypes[] = T_READONLY;

+ 1 - 1
src/Fixer/ClassNotation/ProtectedToPrivateFixer.php

@@ -77,7 +77,7 @@ final class Sample
     protected function applyFix(\SplFileInfo $file, Tokens $tokens): void
     {
         $tokensAnalyzer = new TokensAnalyzer($tokens);
-        $modifierKinds = [T_PUBLIC, T_PROTECTED, T_PRIVATE, T_FINAL, T_ABSTRACT, T_NS_SEPARATOR, T_STRING, CT::T_NULLABLE_TYPE, CT::T_ARRAY_TYPEHINT, T_STATIC, CT::T_TYPE_ALTERNATION];
+        $modifierKinds = [T_PUBLIC, T_PROTECTED, T_PRIVATE, T_FINAL, T_ABSTRACT, T_NS_SEPARATOR, T_STRING, CT::T_NULLABLE_TYPE, CT::T_ARRAY_TYPEHINT, T_STATIC, CT::T_TYPE_ALTERNATION, CT::T_TYPE_INTERSECTION];
 
         if (\defined('T_READONLY')) { // @TODO: drop condition when PHP 8.1+ is required
             $modifierKinds[] = T_READONLY;

+ 1 - 1
src/Fixer/ClassNotation/SingleClassElementPerStatementFixer.php

@@ -212,7 +212,7 @@ final class Example
     private function getModifiersSequences(Tokens $tokens, string $type, int $startIndex, int $endIndex): array
     {
         if ('property' === $type) {
-            $tokenKinds = [T_PUBLIC, T_PROTECTED, T_PRIVATE, T_STATIC, T_VAR, T_STRING, T_NS_SEPARATOR, CT::T_NULLABLE_TYPE, CT::T_ARRAY_TYPEHINT, CT::T_TYPE_ALTERNATION];
+            $tokenKinds = [T_PUBLIC, T_PROTECTED, T_PRIVATE, T_STATIC, T_VAR, T_STRING, T_NS_SEPARATOR, CT::T_NULLABLE_TYPE, CT::T_ARRAY_TYPEHINT, CT::T_TYPE_ALTERNATION, CT::T_TYPE_INTERSECTION];
 
             if (\defined('T_READONLY')) { // @TODO: drop condition when PHP 8.1+ is required
                 $tokenKinds[] = T_READONLY;

+ 1 - 1
src/Fixer/ClassNotation/VisibilityRequiredFixer.php

@@ -98,7 +98,7 @@ class Sample
     {
         $tokensAnalyzer = new TokensAnalyzer($tokens);
 
-        $propertyTypeDeclarationKinds = [T_STRING, T_NS_SEPARATOR, CT::T_NULLABLE_TYPE, CT::T_ARRAY_TYPEHINT, CT::T_TYPE_ALTERNATION];
+        $propertyTypeDeclarationKinds = [T_STRING, T_NS_SEPARATOR, CT::T_NULLABLE_TYPE, CT::T_ARRAY_TYPEHINT, CT::T_TYPE_ALTERNATION, CT::T_TYPE_INTERSECTION];
 
         if (\defined('T_READONLY')) { // @TODO: drop condition when PHP 8.1+ is required
             $propertyReadOnlyType = T_READONLY;

+ 1 - 1
src/Fixer/Import/FullyQualifiedStrictTypesFixer.php

@@ -191,7 +191,7 @@ class SomeClass
                 break;
             }
 
-            if ($tokens[$index]->isGivenKind(CT::T_TYPE_ALTERNATION)) {
+            if ($tokens[$index]->isGivenKind([CT::T_TYPE_ALTERNATION, CT::T_TYPE_INTERSECTION])) {
                 yield ['start' => $startIndex, 'end' => $prevIndex];
                 $startIndex = null;
             }

+ 9 - 1
src/Fixer/Phpdoc/NoSuperfluousPhpdocTagsFixer.php

@@ -186,6 +186,7 @@ class Foo {
             CT::T_NULLABLE_TYPE,
             CT::T_ARRAY_TYPEHINT,
             CT::T_TYPE_ALTERNATION,
+            CT::T_TYPE_INTERSECTION,
             T_STRING,
             T_NS_SEPARATOR,
         ];
@@ -386,7 +387,7 @@ class Foo {
         while (true) {
             $type = '';
 
-            while ($tokens[$index]->isGivenKind([T_NS_SEPARATOR, T_STATIC, T_STRING, CT::T_ARRAY_TYPEHINT, T_CALLABLE])) {
+            while ($tokens[$index]->isGivenKind([T_NS_SEPARATOR, T_STATIC, T_STRING, CT::T_ARRAY_TYPEHINT, T_CALLABLE, CT::T_TYPE_INTERSECTION])) {
                 $type .= $tokens[$index]->getContent();
                 $index = $tokens->getNextMeaningfulToken($index);
             }
@@ -463,6 +464,13 @@ class Foo {
             static function (string $type) use ($symbolShortNames): string {
                 $type = strtolower($type);
 
+                if (str_contains($type, '&')) {
+                    $intersects = explode('&', $type);
+                    sort($intersects);
+
+                    return implode('&', $intersects);
+                }
+
                 return $symbolShortNames[$type] ?? $type;
             },
             $types

+ 2 - 2
src/Fixer/Whitespace/TypesSpacesFixer.php

@@ -59,7 +59,7 @@ final class TypesSpacesFixer extends AbstractFixer implements ConfigurableFixerI
      */
     public function isCandidate(Tokens $tokens): bool
     {
-        return $tokens->isTokenKindFound(CT::T_TYPE_ALTERNATION);
+        return $tokens->isAnyTokenKindsFound([CT::T_TYPE_ALTERNATION, CT::T_TYPE_INTERSECTION]);
     }
 
     /**
@@ -78,7 +78,7 @@ final class TypesSpacesFixer extends AbstractFixer implements ConfigurableFixerI
     protected function applyFix(\SplFileInfo $file, Tokens $tokens): void
     {
         for ($index = $tokens->count() - 1; $index > 0; --$index) {
-            if (!$tokens[$index]->isGivenKind(CT::T_TYPE_ALTERNATION)) {
+            if (!$tokens[$index]->isGivenKind([CT::T_TYPE_ALTERNATION, CT::T_TYPE_INTERSECTION])) {
                 continue;
             }
 

+ 2 - 2
src/Tokenizer/Analyzer/ClassyAnalyzer.php

@@ -41,7 +41,7 @@ final class ClassyAnalyzer
             return false;
         }
 
-        if ($nextToken->isGivenKind([T_DOUBLE_COLON, T_ELLIPSIS, CT::T_TYPE_ALTERNATION, T_VARIABLE])) {
+        if ($nextToken->isGivenKind([T_DOUBLE_COLON, T_ELLIPSIS, CT::T_TYPE_ALTERNATION, CT::T_TYPE_INTERSECTION, T_VARIABLE])) {
             return true;
         }
 
@@ -53,7 +53,7 @@ final class ClassyAnalyzer
 
         $prevToken = $tokens[$prev];
 
-        if ($prevToken->isGivenKind([T_EXTENDS, T_INSTANCEOF, T_INSTEADOF, T_IMPLEMENTS, T_NEW, CT::T_NULLABLE_TYPE, CT::T_TYPE_ALTERNATION, CT::T_TYPE_COLON, CT::T_USE_TRAIT])) {
+        if ($prevToken->isGivenKind([T_EXTENDS, T_INSTANCEOF, T_INSTEADOF, T_IMPLEMENTS, T_NEW, CT::T_NULLABLE_TYPE, CT::T_TYPE_ALTERNATION, CT::T_TYPE_INTERSECTION, CT::T_TYPE_COLON, CT::T_USE_TRAIT])) {
             return true;
         }
 

+ 2 - 6
src/Tokenizer/TokensAnalyzer.php

@@ -312,14 +312,14 @@ final class TokensAnalyzer
 
         if (
             $this->tokens[$nextIndex]->equalsAny(['(', '{'])
-            || $this->tokens[$nextIndex]->isGivenKind([T_AS, T_DOUBLE_COLON, T_ELLIPSIS, T_NS_SEPARATOR, CT::T_RETURN_REF, CT::T_TYPE_ALTERNATION, T_VARIABLE])
+            || $this->tokens[$nextIndex]->isGivenKind([T_AS, T_DOUBLE_COLON, T_ELLIPSIS, T_NS_SEPARATOR, CT::T_RETURN_REF, CT::T_TYPE_ALTERNATION, CT::T_TYPE_INTERSECTION, T_VARIABLE])
         ) {
             return false;
         }
 
         $prevIndex = $this->tokens->getPrevMeaningfulToken($index);
 
-        if ($this->tokens[$prevIndex]->isGivenKind([T_AS, T_CLASS, T_CONST, T_DOUBLE_COLON, T_FUNCTION, T_GOTO, CT::T_GROUP_IMPORT_BRACE_OPEN, T_INTERFACE, T_TRAIT, CT::T_TYPE_COLON, CT::T_TYPE_ALTERNATION]) || $this->tokens[$prevIndex]->isObjectOperator()) {
+        if ($this->tokens[$prevIndex]->isGivenKind([T_AS, T_CLASS, T_CONST, T_DOUBLE_COLON, T_FUNCTION, T_GOTO, CT::T_GROUP_IMPORT_BRACE_OPEN, T_INTERFACE, T_TRAIT, CT::T_TYPE_COLON, CT::T_TYPE_ALTERNATION, CT::T_TYPE_INTERSECTION]) || $this->tokens[$prevIndex]->isObjectOperator()) {
             return false;
         }
 
@@ -380,10 +380,6 @@ final class TokensAnalyzer
         }
 
         // check for non-capturing catches
-        while ($this->tokens[$prevIndex]->isGivenKind([CT::T_TYPE_ALTERNATION, T_STRING])) {
-            $prevIndex = $this->tokens->getPrevMeaningfulToken($prevIndex);
-        }
-
         if ($this->tokens[$prevIndex]->equals('(')) {
             $prevPrevIndex = $this->tokens->getPrevMeaningfulToken($prevIndex);
             if ($this->tokens[$prevPrevIndex]->isGivenKind(T_CATCH)) {

+ 20 - 0
tests/Fixer/ClassNotation/ClassAttributesSeparationFixerTest.php

@@ -2231,5 +2231,25 @@ class Foo
 }
 ',
         ];
+
+        yield 'intersection properties' => [
+            '<?php
+            class Foo {
+                private static Bar & Something & Baz $a;
+
+                private static Bar & Something & Baz $b;
+
+                private Bar & Something & Baz $c;
+
+                private Bar & Something & Baz $d;
+            }',
+            '<?php
+            class Foo {
+                private static Bar & Something & Baz $a;
+                private static Bar & Something & Baz $b;
+                private Bar & Something & Baz $c;
+                private Bar & Something & Baz $d;
+            }',
+        ];
     }
 }

Некоторые файлы не были показаны из-за большого количества измененных файлов