From 184648d236062acd664e61e02d15a9f9599e15a5 Mon Sep 17 00:00:00 2001 From: Caleb White Date: Sun, 20 Sep 2026 23:07:31 -0500 Subject: [PATCH] fix(CodingStyle) keep trait use adaptations in SeparateMultiUseImportsRector Splitting a grouped trait use only carried Alias adaptations across, so an insteadof was dropped along with the statement it sat on: use A, B { A::collide insteadof B; } became two plain uses with nothing left to resolve the conflict, and the class could no longer be loaded at all. An alias naming no trait was dropped just as silently, taking the aliased method with it. Precedence adaptations now follow the trait they name, the same way an alias already did. The two that cannot follow a single trait leave the statement alone instead: one that names no trait applies to all of them, and one that names a trait used in another statement belongs to none of the ones being split. --- ..._use_adaptation_of_other_statement.php.inc | 15 +++++++++ ...p_unqualified_trait_use_adaptation.php.inc | 13 ++++++++ .../Fixture/with_trait_use_precedence.php.inc | 32 +++++++++++++++++++ .../Source/ThirdTrait.php | 13 ++++++++ .../Use_/SeparateMultiUseImportsRector.php | 22 +++++++++++-- 5 files changed, 92 insertions(+), 3 deletions(-) create mode 100644 rules-tests/CodingStyle/Rector/Use_/SeparateMultiUseImportsRector/Fixture/skip_trait_use_adaptation_of_other_statement.php.inc create mode 100644 rules-tests/CodingStyle/Rector/Use_/SeparateMultiUseImportsRector/Fixture/skip_unqualified_trait_use_adaptation.php.inc create mode 100644 rules-tests/CodingStyle/Rector/Use_/SeparateMultiUseImportsRector/Fixture/with_trait_use_precedence.php.inc create mode 100644 rules-tests/CodingStyle/Rector/Use_/SeparateMultiUseImportsRector/Source/ThirdTrait.php diff --git a/rules-tests/CodingStyle/Rector/Use_/SeparateMultiUseImportsRector/Fixture/skip_trait_use_adaptation_of_other_statement.php.inc b/rules-tests/CodingStyle/Rector/Use_/SeparateMultiUseImportsRector/Fixture/skip_trait_use_adaptation_of_other_statement.php.inc new file mode 100644 index 00000000000..81ea1368205 --- /dev/null +++ b/rules-tests/CodingStyle/Rector/Use_/SeparateMultiUseImportsRector/Fixture/skip_trait_use_adaptation_of_other_statement.php.inc @@ -0,0 +1,15 @@ + +----- + diff --git a/rules-tests/CodingStyle/Rector/Use_/SeparateMultiUseImportsRector/Source/ThirdTrait.php b/rules-tests/CodingStyle/Rector/Use_/SeparateMultiUseImportsRector/Source/ThirdTrait.php new file mode 100644 index 00000000000..663f08840e4 --- /dev/null +++ b/rules-tests/CodingStyle/Rector/Use_/SeparateMultiUseImportsRector/Source/ThirdTrait.php @@ -0,0 +1,13 @@ + $trait->toString(), + $traitUse->traits + ); + + foreach ($traitUse->adaptations as $traitAdaptation) { + // an adaptation that names no trait applies to all of them, and one that + // names a trait used elsewhere belongs to no statement here; either way it + // cannot follow a single trait, so the statement is left alone + if (! $traitAdaptation->trait instanceof Name) { + return null; + } + + if (! in_array($traitAdaptation->trait->toString(), $traitNames, true)) { + return null; + } + } + $traitUses = []; foreach ($traitUse->traits as $singleTraitUse) { $adaptation = []; foreach ($traitUse->adaptations as $traitAdaptation) { - if ($traitAdaptation instanceof Alias - && $traitAdaptation->trait instanceof Name + if ($traitAdaptation->trait instanceof Name && $traitAdaptation->trait->toString() === $singleTraitUse->toString()) { $adaptation[] = $traitAdaptation; }