Skip to content

Commit 4c5c195

Browse files
committed
Generic/DuplicateClassName: bug fix - ignore namespace operator
The `namespace` keyword can also be used as an operator, in which case, the sniff as it were would throw false positives. The fix now applies for this incidentally also fixes a nasty bug which could throw the sniff into an eternal loop when an unfinished namespace statement was encountered during live coding. Includes unit tests. **Note**: the unit test for the live coding situation has to be the last unit test file for this sniff so as to not influence the other tests. To that end, it has been numbered `99`.
1 parent d02c686 commit 4c5c195

File tree

3 files changed

+36
-13
lines changed

3 files changed

+36
-13
lines changed

src/Standards/Generic/Sniffs/Classes/DuplicateClassNameSniff.php

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
use PHP_CodeSniffer\Files\File;
1313
use PHP_CodeSniffer\Sniffs\Sniff;
14+
use PHP_CodeSniffer\Util\Tokens;
1415

1516
class DuplicateClassNameSniff implements Sniff
1617
{
@@ -68,19 +69,25 @@ public function process(File $phpcsFile, $stackPtr)
6869

6970
// Keep track of what namespace we are in.
7071
if ($tokens[$stackPtr]['code'] === T_NAMESPACE) {
71-
$nsEnd = $phpcsFile->findNext(
72-
[
73-
T_NS_SEPARATOR,
74-
T_STRING,
75-
T_WHITESPACE,
76-
],
77-
($stackPtr + 1),
78-
null,
79-
true
80-
);
81-
82-
$namespace = trim($phpcsFile->getTokensAsString(($stackPtr + 1), ($nsEnd - $stackPtr - 1)));
83-
$stackPtr = $nsEnd;
72+
$nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true);
73+
if ($nextNonEmpty !== false
74+
// Ignore namespace keyword used as operator.
75+
&& $tokens[$nextNonEmpty]['code'] !== T_NS_SEPARATOR
76+
) {
77+
$nsEnd = $phpcsFile->findNext(
78+
[
79+
T_NS_SEPARATOR,
80+
T_STRING,
81+
T_WHITESPACE,
82+
],
83+
($stackPtr + 1),
84+
null,
85+
true
86+
);
87+
88+
$namespace = trim($phpcsFile->getTokensAsString(($stackPtr + 1), ($nsEnd - $stackPtr - 1)));
89+
$stackPtr = $nsEnd;
90+
}
8491
} else {
8592
$nameToken = $phpcsFile->findNext(T_STRING, $stackPtr);
8693
$name = $tokens[$nameToken]['content'];
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
namespace E;
3+
namespace\functionCall();
4+
class MyClass {}
5+
interface YourInterface {}
6+
7+
namespace F;
8+
namespace\functionCall();
9+
class MyClass {}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
// Intentional parse error/live coding.
4+
// This should be the only test in this file.
5+
// Testing that the sniff is *not* triggered.
6+
7+
namespace

0 commit comments

Comments
 (0)