Repository: PHP-CS-Fixer/PHP-CS-Fixer (php)

Issue:
`ordered_class_elements` and `statement_indentation` produces wrongly indented result when run together
### Problem description

Please checkout the repro branch and run `php php-cs-fixer fix` and notice this wrong indentation in `TypeExpressionTest.php` file:

![image](https://github.com/user-attachments/assets/b527b44e-24b8-4cac-9931-e8ed2a655a52)

### Minimal reproducer

https://github.com/mvorisek/PHP-CS-Fixer/tree/dd

the repro contains only `ordered_class_elements` and `statement_indentation` rules but for some unknown reasons to me, the issue cannot be reproduced when the rules are run separately

### Fixer version

latest - use repro branch

### PHP version

any

Pull request:
fix: Tokens::overrideRange() block cache pruning
critical fix #8228 as currently `Tokens::overrideRange()` might leave the block cache corrupted

needed for #8225

Patch:
diff --git a/src/Tokenizer/Tokens.php b/src/Tokenizer/Tokens.php
index 1000699db..11f919e8d 100644
--- a/src/Tokenizer/Tokens.php
+++ b/src/Tokenizer/Tokens.php
@@ -351,15 +351,17 @@ public function offsetSet($index, $newval): void
             )));
         }
 
+        if (isset($this[$index])) {
+            if (isset($this->blockStartCache[$index])) {
+                unset($this->blockEndCache[$this->blockStartCache[$index]], $this->blockStartCache[$index]);
+            }
+            if (isset($this->blockEndCache[$index])) {
+                unset($this->blockStartCache[$this->blockEndCache[$index]], $this->blockEndCache[$index]);
+            }
+        }
+
         if (!isset($this[$index]) || !$this[$index]->equals($newval)) {
             if (isset($this[$index])) {
-                if (isset($this->blockStartCache[$index])) {
-                    unset($this->blockEndCache[$this->blockStartCache[$index]], $this->blockStartCache[$index]);
-                }
-                if (isset($this->blockEndCache[$index])) {
-                    unset($this->blockStartCache[$this->blockEndCache[$index]], $this->blockEndCache[$index]);
-                }
-
                 $this->unregisterFoundToken($this[$index]);
             }
 


Test patch:
diff --git a/tests/Tokenizer/TokensTest.php b/tests/Tokenizer/TokensTest.php
index 25c8eb43d..e9fe681e2 100644
--- a/tests/Tokenizer/TokensTest.php
+++ b/tests/Tokenizer/TokensTest.php
@@ -1776,6 +1776,36 @@ public function testBlockEdgeCachingOffsetSet(): void
         $tokens->findBlockEnd(Tokens::BLOCK_TYPE_ARRAY_SQUARE_BRACE, 5);
     }
 
+    public function testBlockEdgeCachingOffsetSetPruneEvenIfTokenEquals(): void
+    {
+        $tokens = Tokens::fromArray([
+            new Token([T_OPEN_TAG, '<?php ']),
+            new Token([T_VARIABLE, '$a']),
+            new Token('='),
+            new Token([T_WHITESPACE, ' ']),
+            new Token([CT::T_ARRAY_SQUARE_BRACE_OPEN, '[']),
+            new Token([T_WHITESPACE, ' ']),
+            new Token([CT::T_ARRAY_SQUARE_BRACE_CLOSE, ']']),
+            new Token(';'),
+        ]);
+
+        self::assertSame(6, $tokens->findBlockEnd(Tokens::BLOCK_TYPE_ARRAY_SQUARE_BRACE, 4));
+        self::assertSame(4, $tokens->findBlockStart(Tokens::BLOCK_TYPE_ARRAY_SQUARE_BRACE, 6));
+
+        $tokens->overrideRange(3, 6, [
+            new Token([CT::T_ARRAY_SQUARE_BRACE_OPEN, '[']),
+            $tokens[4],
+            new Token([CT::T_ARRAY_SQUARE_BRACE_CLOSE, ']']),
+            $tokens[6],
+        ]);
+
+        self::assertSame(5, $tokens->findBlockEnd(Tokens::BLOCK_TYPE_ARRAY_SQUARE_BRACE, 4));
+        self::assertSame(4, $tokens->findBlockStart(Tokens::BLOCK_TYPE_ARRAY_SQUARE_BRACE, 5));
+
+        self::assertSame(6, $tokens->findBlockEnd(Tokens::BLOCK_TYPE_ARRAY_SQUARE_BRACE, 3));
+        self::assertSame(3, $tokens->findBlockStart(Tokens::BLOCK_TYPE_ARRAY_SQUARE_BRACE, 6));
+    }
+
     public function testBlockEdgeCachingClearAt(): void
     {
         $tokens = $this->getBlockEdgeCachingTestTokens();