Skip to content

Commit

Permalink
Merge pull request #132 from PHPCSStandards/feature/namespace-get-typ…
Browse files Browse the repository at this point in the history
…e-improve-operator-detection

Namespaces::getType(): improve detection of namespace keyword as operator
  • Loading branch information
jrfnl committed May 1, 2020
2 parents 442f5d3 + 49324bb commit 0fa0724
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 5 deletions.
26 changes: 24 additions & 2 deletions PHPCSUtils/Utils/Namespaces.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Util\Tokens;
use PHPCSUtils\BackCompat\BCFile;
use PHPCSUtils\BackCompat\BCTokens;
use PHPCSUtils\Tokens\Collections;
use PHPCSUtils\Utils\Conditions;
use PHPCSUtils\Utils\GetTokensAsString;
Expand Down Expand Up @@ -46,6 +47,26 @@ class Namespaces
*/
public static function getType(File $phpcsFile, $stackPtr)
{
static $findAfter;

if (isset($findAfter) === false) {
/*
* Set up array of tokens which can only be used in combination with the keyword as operator
* and which cannot be confused with other keywords.
*/
$findAfter = BCTokens::assignmentTokens()
+ BCTokens::comparisonTokens()
+ BCTokens::operators()
+ Tokens::$castTokens
+ Tokens::$blockOpeners
+ Collections::$incrementDecrementOperators
+ Collections::$objectOperators;

$findAfter[\T_OPEN_CURLY_BRACKET] = \T_OPEN_CURLY_BRACKET;
$findAfter[\T_OPEN_SQUARE_BRACKET] = \T_OPEN_SQUARE_BRACKET;
$findAfter[\T_OPEN_SHORT_ARRAY] = \T_OPEN_SHORT_ARRAY;
}

$tokens = $phpcsFile->getTokens();

if (isset($tokens[$stackPtr]) === false || $tokens[$stackPtr]['code'] !== \T_NAMESPACE) {
Expand Down Expand Up @@ -80,8 +101,9 @@ public static function getType(File $phpcsFile, $stackPtr)
return 'declaration';
}

if ($start !== $stackPtr
&& $tokens[$next]['code'] === \T_NS_SEPARATOR
if ($tokens[$next]['code'] === \T_NS_SEPARATOR
&& ($start !== $stackPtr
|| $phpcsFile->findNext($findAfter, ($stackPtr + 1), null, false, null, true) !== false)
) {
return 'operator';
}
Expand Down
19 changes: 16 additions & 3 deletions Tests/Utils/Namespaces/NamespaceTypeTest.inc
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,24 @@ function closedScope() {
echo namespace\ClassName::method();

while( true ) {
/* testNamespaceOperatorInParentheses */
function_call( namespace\ClassName::$property );
}
/* testNamespaceOperatorInParentheses */
function_call( namespace\ClassName::$property );
}
}

/* testNamespaceOperatorGlobalNamespaceStartOfStatementFunctionCall */
namespace\functionCall();

/* testNamespaceOperatorGlobalNamespaceStartOfStatementCombiWithNonConfusingToken1 */
namespace\CONSTANT === 'test' or die();

/* testNamespaceOperatorGlobalNamespaceStartOfStatementCombiWithNonConfusingToken2 */
namespace\ClassName::$property++;

/* testNamespaceOperatorGlobalNamespaceStartOfStatementCombiWithNonConfusingToken3 */
namespace\CONSTANT['key'];


/* testParseErrorScopedNamespaceDeclaration */
function testScope() {
namespace My\Namespace;
Expand Down
28 changes: 28 additions & 0 deletions Tests/Utils/Namespaces/NamespaceTypeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,34 @@ public function dataNamespaceType()
'operator' => true,
],
],
'namespace-operator-global-namespace-start-of-statement-function-call' => [
'/* testNamespaceOperatorGlobalNamespaceStartOfStatementFunctionCall */',
[
'declaration' => false,
'operator' => true,
],
],
'namespace-operator-global-namespace-start-of-statement-with-non-confusing-token-1' => [
'/* testNamespaceOperatorGlobalNamespaceStartOfStatementCombiWithNonConfusingToken1 */',
[
'declaration' => false,
'operator' => true,
],
],
'namespace-operator-global-namespace-start-of-statement-with-non-confusing-token-2' => [
'/* testNamespaceOperatorGlobalNamespaceStartOfStatementCombiWithNonConfusingToken2 */',
[
'declaration' => false,
'operator' => true,
],
],
'namespace-operator-global-namespace-start-of-statement-with-non-confusing-token-3' => [
'/* testNamespaceOperatorGlobalNamespaceStartOfStatementCombiWithNonConfusingToken3 */',
[
'declaration' => false,
'operator' => true,
],
],
'parse-error-scoped-namespace-declaration' => [
'/* testParseErrorScopedNamespaceDeclaration */',
[
Expand Down

0 comments on commit 0fa0724

Please sign in to comment.