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

Issue:
binary_operator_spaces adding whitespace around hyphen outside php block
## Bug report

PHP-CS-Fixer is incorrectly treating hyphens outside PHP block in my template files as Subtraction operator and adding whitespace around it.

#### Version Info
```
$ php-cs-fixer -V
PHP CS Fixer 3.8.0 (cbad111) BerSzcz against war! by Fabien Potencier and Dariusz Ruminski.
PHP runtime: 8.1.7
```

#### Reproducable Example
```php
<?php
// test.php
$id = 1;
$path = 'test';
?>

<a href="test-<?=$path?>-<?=$id?>.html">Test</a>
```

```php
<?php
// .php-cs-fixer.dist.php

// for more info see:
// https://github.com/FriendsOfPHP/PHP-CS-Fixer#usage
// https://github.com/FriendsOfPHP/PHP-CS-Fixer/blob/master/UPGRADE.md

$finder = PhpCsFixer\Finder::create()
    ->in(__DIR__)
;

return (new PhpCsFixer\Config())
    ->setRules([
        'binary_operator_spaces' => true,
    ])
    ->setLineEnding("\n")
    ->setFinder($finder)
;
```


```diff
php-cs-fixer fix --dry-run --diff test.php                                                                     ⎈ docker-desktop 13:58:24
Loaded config default from "/private/tmp/test/.php-cs-fixer.dist.php".
Using cache file ".php-cs-fixer.cache".
Paths from configuration file have been overridden by paths provided as command arguments.
   1) test.php
      ---------- begin diff ----------
--- /private/tmp/test/test.php
+++ /private/tmp/test/test.php
@@ -3,4 +3,4 @@
 $path = 'test';
 ?>

-<a href="test-<?=$path?>-<?=$id?>.html">Test</a>
+<a href="test-<?=$path?> - <?=$id?>.html">Test</a>

      ----------- end diff -----------
```

#### Expected Output

PHP-CS-Fixer should not modify content outside PHP block.

<!--
  Before reporting a bug, make sure PHP CS Fixer is up-to-date.

  Please describe the problem and provide technical details such as:
   * PHP CS Fixer version and PHP runtime: php-cs-fixer -V
   * the command used to run PHP CS Fixer (run with `-vvv`)
   * the configuration (file) you used
-->

### Code snippet that reproduces the problem

<!--
  Provide a minimal code snippet before running PHP CS Fixer. If relevant,
  also provide the expected output, the actual output and/or the error that
  occurred, if any.

  Please use markdown syntax for each code snippet, e.g.:

  ```php
  <?php
  $var = 'foo';
  ```
-->


Pull request:
bug: Fix BinaryOperatorSpacesFixer adding whitespace outside PHP blocks
Prevents `TokensAnalyzer::isBinaryOperator()` from treating `[T_INLINE_HTML, '-']` as operator. Fixes #6443.

Patch:
diff --git a/src/Fixer/Basic/CurlyBracesPositionFixer.php b/src/Fixer/Basic/CurlyBracesPositionFixer.php
index f0f99c67c..d2b7f7beb 100644
--- a/src/Fixer/Basic/CurlyBracesPositionFixer.php
+++ b/src/Fixer/Basic/CurlyBracesPositionFixer.php
@@ -255,7 +255,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void
                 $previousTokenIndex = $openBraceIndex;
                 do {
                     $previousTokenIndex = $tokens->getPrevMeaningfulToken($previousTokenIndex);
-                } while ($tokens[$previousTokenIndex]->isGivenKind([CT::T_TYPE_COLON, CT::T_NULLABLE_TYPE, T_STRING, T_NS_SEPARATOR, CT::T_ARRAY_TYPEHINT]));
+                } while ($tokens[$previousTokenIndex]->isGivenKind([CT::T_TYPE_COLON, CT::T_NULLABLE_TYPE, T_STRING, T_NS_SEPARATOR, CT::T_ARRAY_TYPEHINT, CT::T_TYPE_ALTERNATION, CT::T_TYPE_INTERSECTION]));
 
                 if ($tokens[$previousTokenIndex]->equals(')')) {
                     if ($tokens[--$previousTokenIndex]->isComment()) {
diff --git a/src/Tokenizer/TokensAnalyzer.php b/src/Tokenizer/TokensAnalyzer.php
index 3995b56e4..918908096 100644
--- a/src/Tokenizer/TokensAnalyzer.php
+++ b/src/Tokenizer/TokensAnalyzer.php
@@ -562,7 +562,7 @@ public function isBinaryOperator(int $index): bool
         $tokens = $this->tokens;
         $token = $tokens[$index];
 
-        if ($token->isGivenKind([T_ENCAPSED_AND_WHITESPACE, CT::T_TYPE_INTERSECTION])) {
+        if ($token->isGivenKind([T_INLINE_HTML, T_ENCAPSED_AND_WHITESPACE, CT::T_TYPE_INTERSECTION])) {
             return false;
         }
 


Test patch:
diff --git a/tests/Fixer/Basic/CurlyBracesPositionFixerTest.php b/tests/Fixer/Basic/CurlyBracesPositionFixerTest.php
index 7b99b50e3..4f3b6f502 100644
--- a/tests/Fixer/Basic/CurlyBracesPositionFixerTest.php
+++ b/tests/Fixer/Basic/CurlyBracesPositionFixerTest.php
@@ -645,4 +645,55 @@ function foo(
                 }',
         ];
     }
+
+    /**
+     * @dataProvider provideFix80Cases
+     * @requires PHP 8.0
+     */
+    public function testFix80(string $expected, ?string $input = null): void
+    {
+        $this->doTest($expected, $input);
+    }
+
+    public function provideFix80Cases(): iterable
+    {
+        yield 'function (multiline + union return)' => [
+            '<?php
+                function sum(
+                    int|float $first,
+                    int|float $second,
+                ): int|float {
+                }',
+        ];
+
+        yield 'function (multiline + union return with whitespace)' => [
+            '<?php
+                function sum(
+                    int|float $first,
+                    int|float $second,
+                ): int | float {
+                }',
+        ];
+    }
+
+    /**
+     * @dataProvider provideFix81Cases
+     * @requires PHP 8.1
+     */
+    public function testFix81(string $expected, ?string $input = null): void
+    {
+        $this->doTest($expected, $input);
+    }
+
+    public function provideFix81Cases(): iterable
+    {
+        yield 'function (multiline + intersection return)' => [
+            '<?php
+                function foo(
+                    mixed $bar,
+                    mixed $baz,
+                ): Foo&Bar {
+                }',
+        ];
+    }
 }
diff --git a/tests/Fixer/Operator/BinaryOperatorSpacesFixerTest.php b/tests/Fixer/Operator/BinaryOperatorSpacesFixerTest.php
index a7217bf6a..3822670e3 100644
--- a/tests/Fixer/Operator/BinaryOperatorSpacesFixerTest.php
+++ b/tests/Fixer/Operator/BinaryOperatorSpacesFixerTest.php
@@ -708,6 +708,7 @@ public function provideFixCases(): array
 $b;
 ',
             ],
+            ['<a href="test-<?=$path?>-<?=$id?>.html">Test</a>'],
         ];
     }
 
diff --git a/tests/Tokenizer/TokensAnalyzerTest.php b/tests/Tokenizer/TokensAnalyzerTest.php
index 300725c9b..7de74b7a5 100644
--- a/tests/Tokenizer/TokensAnalyzerTest.php
+++ b/tests/Tokenizer/TokensAnalyzerTest.php
@@ -1579,6 +1579,10 @@ public function provideIsBinaryOperatorCases(): iterable
                 [9 => false],
                 '<?php $a = "{$value}-{$theSwitch}";',
             ],
+            [
+                [3 => false],
+                '<?=$path?>-<?=$id?>',
+            ],
         ];
 
         $operators = [