1010use \SlevomatCodingStandard \Helpers \AnnotationHelper ;
1111use \SlevomatCodingStandard \Helpers \ClassHelper ;
1212use \SlevomatCodingStandard \Helpers \CommentHelper ;
13- use \SlevomatCodingStandard \Helpers \ConstantHelper ;
14- use \SlevomatCodingStandard \Helpers \FunctionHelper ;
1513use \SlevomatCodingStandard \Helpers \NamespaceHelper ;
1614use \SlevomatCodingStandard \Helpers \ReferencedNameHelper ;
1715use \SlevomatCodingStandard \Helpers \StringHelper ;
@@ -54,9 +52,7 @@ public function process(File $phpcsFile, $openTagPointer) : void
5452 }
5553
5654 $ tokens = $ phpcsFile ->getTokens ();
57- 5855 $ references = $ this ->getReferences ($ phpcsFile , $ openTagPointer );
59- 6056 $ definedClassesIndex = [];
6157
6258 foreach (ClassHelper::getAllNames ($ phpcsFile ) as $ definedClassPointer => $ definedClassName ) {
@@ -67,11 +63,6 @@ public function process(File $phpcsFile, $openTagPointer) : void
6763 );
6864 }
6965
70- $ definedFunctionsIndex = \array_flip (\array_map (static function (string $ functionName ) : string {
71- return \strtolower ($ functionName );
72- }, FunctionHelper::getAllFunctionNames ($ phpcsFile )));
73- $ definedConstantsIndex = \array_flip (ConstantHelper::getAllNames ($ phpcsFile ));
74- 7566 $ classReferencesIndex = [];
7667 $ classReferences = \array_filter ($ references , static function (\stdClass $ reference ) : bool {
7768 return $ reference ->source === self ::SOURCE_CODE && $ reference ->isClass ;
@@ -106,29 +97,6 @@ public function process(File $phpcsFile, $openTagPointer) : void
10697 $ startPointer = $ reference ->startPointer ;
10798 $ canonicalName = NamespaceHelper::normalizeToCanonicalName ($ name );
10899 $ isFullyQualified = NamespaceHelper::isFullyQualifiedName ($ name );
109- $ isGlobalFallback = !$ isFullyQualified
110- && !NamespaceHelper::hasNamespace ($ name )
111- && $ namespacePointers !== []
112- && !\array_key_exists (UseStatement::getUniqueId ($ reference ->type , $ name ), $ useStatements );
113- $ isGlobalFunctionFallback = false ;
114- 115- if ($ reference ->isFunction && $ isGlobalFallback ) {
116- $ isGlobalFunctionFallback = !\array_key_exists (\strtolower ($ reference ->name ), $ definedFunctionsIndex ) && \function_exists (
117- $ reference ->name ,
118- );
119- }
120- 121- $ isGlobalConstantFallback = false ;
122- 123- if ($ reference ->isConstant && $ isGlobalFallback ) {
124- $ isGlobalConstantFallback = !\array_key_exists ($ reference ->name , $ definedConstantsIndex ) && \defined ($ reference ->name );
125- }
126- 127- if ($ isFullyQualified || $ isGlobalFunctionFallback || $ isGlobalConstantFallback ) {
128- if ($ isFullyQualified && !$ this ->isRequiredToBeUsed ($ name )) {
129- continue ;
130- }
131- }
132100
133101 if ($ reference ->isClass === true && !NamespaceHelper::hasNamespace ($ name ) && $ isFullyQualified ) {
134102 continue ;
@@ -220,8 +188,6 @@ public function process(File $phpcsFile, $openTagPointer) : void
220188 $ referenceErrors [] = (object ) [
221189 'reference ' => $ reference ,
222190 'canonicalName ' => $ canonicalName ,
223- 'isGlobalConstantFallback ' => $ isGlobalConstantFallback ,
224- 'isGlobalFunctionFallback ' => $ isGlobalFunctionFallback ,
225191 'reason ' => $ reason ,
226192 ];
227193 }
@@ -243,14 +209,9 @@ public function process(File $phpcsFile, $openTagPointer) : void
243209 $ reference = $ referenceData ->reference ;
244210 $ startPointer = $ reference ->startPointer ;
245211 $ canonicalName = $ referenceData ->canonicalName ;
246- $ nameToReference = NamespaceHelper::getUnqualifiedNameFromFullyQualifiedName ($ reference ->name );
247- $ canonicalNameToReference = $ reference ->isConstant
248- ? $ nameToReference
249- : \strtolower ($ nameToReference );
250- $ isGlobalConstantFallback = $ referenceData ->isGlobalConstantFallback ;
251- $ isGlobalFunctionFallback = $ referenceData ->isGlobalFunctionFallback ;
252- 253212 $ useStatements = UseStatementHelper::getUseStatementsForPointer ($ phpcsFile , $ reference ->startPointer );
213+ [$ nameToReference , $ isConflicting ] = $ this ->getNormalizedClassName ($ reference ->name , $ useStatements );
214+ $ canonicalNameToReference = \strtolower ($ nameToReference );
254215
255216 $ canBeFixed = \array_reduce (
256217 $ alreadyAddedUses [$ reference ->type ],
@@ -276,8 +237,6 @@ static function (bool $carry, string $use) use ($canonicalName) : bool {
276237 && \array_key_exists ($ canonicalNameToReference , $ classReferencesIndex )
277238 && $ canonicalName !== NamespaceHelper::normalizeToCanonicalName ($ classReferencesIndex [$ canonicalNameToReference ])
278239 )
279- || ($ reference ->isFunction && \array_key_exists ($ canonicalNameToReference , $ definedFunctionsIndex ))
280- || ($ reference ->isConstant && \array_key_exists ($ canonicalNameToReference , $ definedConstantsIndex ))
281240 ) {
282241 $ canBeFixed = false ;
283242 }
@@ -301,12 +260,11 @@ static function (bool $carry, string $use) use ($canonicalName) : bool {
301260 }
302261
303262 $ label = \sprintf ('Class %s ' , $ reference ->name );
304- $ errorCode = $ isGlobalConstantFallback || $ isGlobalFunctionFallback
305- ? self ::CODE_REFERENCE_VIA_FALLBACK_GLOBAL_NAME
306- : self ::CODE_REFERENCE_VIA_FULLY_QUALIFIED_NAME ;
307- $ errorMessage = $ isGlobalConstantFallback || $ isGlobalFunctionFallback
308- ? \sprintf ('%s should not be referenced via a fallback global name, but via a use statement ' . $ referenceData ->reason , $ label )
309- : \sprintf ('%s should not be referenced via a fully qualified name, but via a use statement ' . $ referenceData ->reason , $ label );
263+ $ errorCode = self ::CODE_REFERENCE_VIA_FULLY_QUALIFIED_NAME ;
264+ $ errorMessage = \sprintf (
265+ '%s should not be referenced via a fully qualified name, but via a use statement ' . $ referenceData ->reason ,
266+ $ label ,
267+ );
310268
311269 if (!$ canBeFixed ) {
312270 $ phpcsFile ->addError ($ errorMessage , $ startPointer , $ errorCode );
@@ -347,7 +305,15 @@ static function (bool $carry, string $use) use ($canonicalName) : bool {
347305 : '' ;
348306
349307 $ phpcsFile ->fixer ->addNewline ($ useStatementPlacePointer );
350- $ phpcsFile ->fixer ->addContent ($ useStatementPlacePointer , \sprintf ('use %s%s; ' , $ useTypeFormatted , $ canonicalName ));
308+ 309+ if ($ isConflicting === true ) {
310+ $ phpcsFile ->fixer ->addContent (
311+ $ useStatementPlacePointer ,
312+ \sprintf ('use %s%s as %s; ' , $ useTypeFormatted , $ canonicalName , $ nameToReference ),
313+ );
314+ } else {
315+ $ phpcsFile ->fixer ->addContent ($ useStatementPlacePointer , \sprintf ('use %s%s; ' , $ useTypeFormatted , $ canonicalName ));
316+ }
351317
352318 $ alreadyAddedUses [$ reference ->type ][] = $ canonicalName ;
353319 }
@@ -388,11 +354,6 @@ static function (bool $carry, string $use) use ($canonicalName) : bool {
388354 $ phpcsFile ->fixer ->endChangeset ();
389355 }
390356
391- private function isRequiredToBeUsed (string $ name ) : bool
392- {
393- return true ;
394- }
395- 396357 private function getUseStatementPlacePointer (\PHP_CodeSniffer \Files \File $ phpcsFile , int $ openTagPointer , array $ useStatements ) : int
397358 {
398359 if (\count ($ useStatements ) !== 0 ) {
@@ -475,4 +436,43 @@ private function getReferences(\PHP_CodeSniffer\Files\File $phpcsFile, int $open
475436
476437 return $ references ;
477438 }
439+ 440+ private function getNormalizedClassName (string $ name , array $ useStatements ) : array
441+ {
442+ $ unqualifiedName = NamespaceHelper::getUnqualifiedNameFromFullyQualifiedName ($ name );
443+ 444+ foreach ($ useStatements as $ useStatement ) {
445+ $ useStatementUnqualified = NamespaceHelper::getUnqualifiedNameFromFullyQualifiedName ($ useStatement ->getFullyQualifiedTypeName ());
446+ 447+ if ($ unqualifiedName !== $ useStatementUnqualified ) {
448+ continue ;
449+ }
450+ 451+ $ nameSplit = \explode ('\\' , \ltrim ($ name , '\\' ));
452+ $ useStatementSplit = \explode ('\\' , \ltrim ($ useStatement ->getFullyQualifiedTypeName (), '\\' ));
453+ 454+ $ i = 0 ;
455+ $ toUse = null ;
456+ 457+ foreach ($ nameSplit as $ value ) {
458+ if (!isset ($ useStatementSplit [$ i ])) {
459+ break ;
460+ }
461+ 462+ if (\substr ($ value , 0 , 1 ) !== \substr ($ useStatementSplit [$ i ], 0 , 1 )) {
463+ $ toUse = \substr ($ value , 0 , 1 );
464+ 465+ break ;
466+ }
467+ 468+ $ i ++;
469+ }
470+ 471+ return $ toUse === null
472+ ? [$ unqualifiedName , false ]
473+ : [$ toUse . $ unqualifiedName , true ];
474+ }
475+ 476+ return [$ unqualifiedName , false ];
477+ }
478478}
0 commit comments