44
55namespace Rector \CodingStyle \Node ;
66
7+ use PhpParser \Node \Identifier ;
78use PhpParser \Node \Name ;
89use PhpParser \Node \Name \FullyQualified ;
10+ use PhpParser \Node \Stmt \GroupUse ;
11+ use PhpParser \Node \Stmt \Use_ ;
912use Rector \CodingStyle \ClassNameImport \ClassNameImportSkipper ;
10- use Rector \Configuration \Option ;
11- use Rector \Configuration \Parameter \SimpleParameterProvider ;
13+ use Rector \Naming \Naming \AliasNameResolver ;
1214use Rector \NodeTypeResolver \Node \AttributeKey ;
1315use Rector \PostRector \Collector \UseNodesToAddCollector ;
1416use Rector \StaticTypeMapper \PhpParser \FullyQualifiedNodeMapper ;
2022 public function __construct (
2123 private ClassNameImportSkipper $ classNameImportSkipper ,
2224 private FullyQualifiedNodeMapper $ fullyQualifiedNodeMapper ,
23- private UseNodesToAddCollector $ useNodesToAddCollector
25+ private UseNodesToAddCollector $ useNodesToAddCollector ,
26+ private AliasNameResolver $ aliasNameResolver
2427 ) {
2528 }
2629
27- public function importName (FullyQualified $ fullyQualified , File $ file ): ?Name
30+ /**
31+ * @param array<Use_|GroupUse> $currentUses
32+ */
33+ public function importName (FullyQualified $ fullyQualified , File $ file , array $ currentUses ): ?Name
2834 {
29- if ($ this ->shouldSkipName ($ fullyQualified )) {
35+ if ($ this ->classNameImportSkipper -> shouldSkipName ($ fullyQualified, $ currentUses )) {
3036 return null ;
3137 }
3238
@@ -35,36 +41,55 @@ public function importName(FullyQualified $fullyQualified, File $file): ?Name
3541 return null ;
3642 }
3743
38- return $ this ->importNameAndCollectNewUseStatement ($ file , $ fullyQualified , $ staticType );
44+ return $ this ->importNameAndCollectNewUseStatement ($ file , $ fullyQualified , $ staticType, $ currentUses );
3945 }
4046
41- private function shouldSkipName (FullyQualified $ fullyQualified ): bool
47+ /**
48+ * @param array<Use_|GroupUse> $currentUses
49+ */
50+ private function resolveNameInUse (FullyQualified $ fullyQualified , array $ currentUses ): ?Name
4251 {
43- // is scalar name?
44- if (in_array ( $ fullyQualified -> toLowerString (), [ ' true ' , ' false ' , ' bool ' ], true )) {
45- return true ;
52+ $ aliasName = $ this -> aliasNameResolver -> resolveByName ( $ fullyQualified , $ currentUses );
53+ if (is_string ( $ aliasName )) {
54+ return new Name ( $ aliasName ) ;
4655 }
4756
48- if ($ this -> isFunctionOrConstantImportWithSingleName ( $ fullyQualified ) ) {
49- return true ;
57+ if (substr_count ( $ fullyQualified -> toCodeString (), '\\' ) === 1 ) {
58+ return null ;
5059 }
5160
52- // Importing root namespace classes (like \DateTime) is optional
53- if (! SimpleParameterProvider::provideBoolParameter (Option::IMPORT_SHORT_CLASSES )) {
54- $ stringName = $ fullyQualified ->toString ();
55- if (substr_count ($ stringName , '\\' ) === 0 ) {
56- return true ;
61+ $ lastName = $ fullyQualified ->getLast ();
62+ foreach ($ currentUses as $ currentUse ) {
63+ foreach ($ currentUse ->uses as $ useUse ) {
64+ if ($ useUse ->name ->getLast () !== $ lastName ) {
65+ continue ;
66+ }
67+
68+ if ($ useUse ->alias instanceof Identifier && $ useUse ->alias ->toString () !== $ lastName ) {
69+ return new Name ($ lastName );
70+ }
5771 }
5872 }
5973
60- return false ;
74+ return null ;
6175 }
6276
77+ /**
78+ * @param array<Use_|GroupUse> $currentUses
79+ */
6380 private function importNameAndCollectNewUseStatement (
6481 File $ file ,
6582 FullyQualified $ fullyQualified ,
66- FullyQualifiedObjectType $ fullyQualifiedObjectType
83+ FullyQualifiedObjectType $ fullyQualifiedObjectType ,
84+ array $ currentUses
6785 ): ?Name {
86+ // make use of existing use import
87+ $ nameInUse = $ this ->resolveNameInUse ($ fullyQualified , $ currentUses );
88+ if ($ nameInUse instanceof Name) {
89+ $ nameInUse ->setAttribute (AttributeKey::NAMESPACED_NAME , $ fullyQualified ->toString ());
90+ return $ nameInUse ;
91+ }
92+
6893 // the same end is already imported → skip
6994 if ($ this ->classNameImportSkipper ->shouldSkipNameForFullyQualifiedObjectType (
7095 $ file ,
@@ -86,19 +111,6 @@ private function importNameAndCollectNewUseStatement(
86111 return $ fullyQualifiedObjectType ->getShortNameNode ();
87112 }
88113
89- private function isFunctionOrConstantImportWithSingleName (FullyQualified $ fullyQualified ): bool
90- {
91- if ($ fullyQualified ->getAttribute (AttributeKey::IS_CONSTFETCH_NAME ) === true ) {
92- return count ($ fullyQualified ->getParts ()) === 1 ;
93- }
94-
95- if ($ fullyQualified ->getAttribute (AttributeKey::IS_FUNCCALL_NAME ) === true ) {
96- return count ($ fullyQualified ->getParts ()) === 1 ;
97- }
98-
99- return false ;
100- }
101-
102114 private function addUseImport (
103115 File $ file ,
104116 FullyQualified $ fullyQualified ,
0 commit comments