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

Issue:
Group imports failing on renamed imports (use... as...)
## Bug report

When running php-cs-fixer on this file this error happens:

![image](https://user-images.githubusercontent.com/2331052/140408762-d017f53a-e4d1-44e0-bc37-05b4b3905b3b.png)

And here's my config file: https://gist.github.com/d8vjork/a8e0d39d2e13cb60d41c45f56fca56f4

So what I think happens is that the commas for make the union for those `use Class as Renamed` are failing with the group imports, but correct me if I'm wrong on this.

### Code snippet that reproduces the problem

```php
<?php

namespace App\Models;

use App\Builders\RevisionBuilder;
use App\Contracts\HasStyleRules;
use App\Contracts\HasDiagramTemplate as ContractsHasDiagramTemplate;
use App\Contracts\HasForms as ContractsHasForms;
use App\Contracts\HasStylesheet as ContractsHasStylesheet;
use App\Enums\RevisionType;
use App\Http\Resources\RevisionResource;
use App\Models\Traits\Revision\HasMilestones;
use App\Models\Traits\Revisions\HasForms;
use App\Models\Traits\{HasDiagramTemplate, HasStylesheet};
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\SoftDeletes;
use SkoreLabs\LaravelAuditable\Traits\Auditable;
use SkoreLabs\LaravelStatus\Contracts\Statusable;
use SkoreLabs\LaravelStatus\Traits\HasStatuses;

// Rest of code...
```



Discussion:
Thanks for reporting!

Minimal issue to reproduce on latest `master`:

```php
<?php

namespace Foo\Bar;

use A\B as X;
use A\C as Y;
```

crashes `GroupImportFixer`

```php
<?php

namespace X\Y;

use A\B as X;
use A\C as Y;
use B\C;
```

yield some odds results, including repeating T_WHITESPACE token... I suspect the same cause

Reproduced on `3.16-DEV` (current master). `group_import` applies patch, but incorrectly - `use` is trimmed from following import, but at the same time is added to one of aliases (`useContractsHasForms` here).

![image](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/assets/600668/64a63343-2b52-46be-aef5-2396f6cf6f5d)

@SpacePossum's minimal reproducer is fixed by `group_import` to:

```php
<?php

namespace X\Y;

use A\{B as X, C as useY};
 B\C;
```

It does not causes `LintingException` after that, and running `ordered_imports` (separate execution) on that changed file also does not produce linting error, so file's technically OK (but is malformed logically because of `use` being moved to wrong place). *It only fails when those 2 fixers are run consecutively in the same execution* (`--rules=group_import,ordered_imports`).

After further investigation it seems like imports are not parsed properly:

![image](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/assets/600668/f7076ec4-94c5-4f59-a35d-1ebaa7d294b4)

It looks like additional problem is somewhere in [these lines](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/blob/a2e9e7410792e0532116ba2adfccb9e776d89771/src/Fixer/Import/OrderedImportsFixer.php#L196-L214). `$usesOrder` produced there is then iterated and for each element `Tokens::fromCode()` is used, which uses `Tokens::setCode()` internally and then exception happens.

Let's sum it up, we have 2 problems:
- `group_import` not handling aliases correctly, which moves `use` keyword from the import to one of aliases (which is the root cause of whole issue)
- `ordered_imports` parsing imports wrongly, by creating namespaces like `}` for @SpacePossum' snippet, `, HasStyleRules, HasStylesheet as  ContractsHasStylesheet}` for @d8vjork's snippet (which is the side effect, because it uses tokenized version of the file from previous fixer's run, and probably navigates from one `use` to another)

I hope it will help someone to fix it 😉.
I am blind probably, I did not see there was linked PR which was closed 🤦‍♂️. I cherry-picked it, added small improvement and I think it can be merged because it works as expected without breaking anything that already was in test cases 🙂.



Patch:
diff --git a/src/Fixer/Import/GroupImportFixer.php b/src/Fixer/Import/GroupImportFixer.php
index d6e4351d526..fc93d034ae3 100644
--- a/src/Fixer/Import/GroupImportFixer.php
+++ b/src/Fixer/Import/GroupImportFixer.php
@@ -208,7 +208,7 @@ private function insertToGroupUseWithAlias(Tokens $tokens, int $insertIndex, Nam
 
         $tokens->insertAt($insertIndex, $newTokens);
 
-        return \count($newTokens) + 1;
+        return \count($newTokens);
     }
 
     /**
@@ -252,15 +252,14 @@ private function createNewGroup(Tokens $tokens, int $insertIndex, NamespaceUseAn
         $insertIndex += $newTokensCount;
 
         if ($useDeclaration->isAliased()) {
-            $inserted = $this->insertToGroupUseWithAlias($tokens, $insertIndex + 1, $useDeclaration);
+            $inserted = $this->insertToGroupUseWithAlias($tokens, $insertIndex + 1, $useDeclaration) + 1;
             $insertedTokens += $inserted;
             $insertIndex += $inserted;
         }
 
         $tokens->insertAt($insertIndex, new Token([T_STRING, $useDeclaration->getShortName()]));
-        ++$insertedTokens;
 
-        return $insertedTokens;
+        return ++$insertedTokens;
     }
 
     /**


Test patch:
diff --git a/tests/Fixer/Import/GroupImportFixerTest.php b/tests/Fixer/Import/GroupImportFixerTest.php
index fec96da8431..cd4dfc13735 100644
--- a/tests/Fixer/Import/GroupImportFixerTest.php
+++ b/tests/Fixer/Import/GroupImportFixerTest.php
@@ -37,6 +37,38 @@ public static function provideFixCases(): iterable
     {
         yield [
             '<?php
+namespace X1\Y1;
+
+use A\{B as X, C as Y};
+use B\C;
+',
+            '<?php
+namespace X1\Y1;
+
+use A\B as X;
+use A\C as Y;
+use B\C;
+',
+        ];
+
+        yield [
+            '<?php
+
+namespace Foo\Bar;
+
+use A\{B as X, C as Y};
+',
+            '<?php
+
+namespace Foo\Bar;
+
+use A\B as X;
+use A\C as Y;
+',
+        ];
+
+        yield [
+            '<?php
 
 namespace Test;