Skip to content

Commit

Permalink
Merge branch 'feature/3326-generic-multiplestatementalignment-bugfix'…
Browse files Browse the repository at this point in the history
  • Loading branch information
gsherwood committed Jun 30, 2021
2 parents bf08940 + 0d5663c commit 7559324
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -468,3 +468,13 @@ $resource = new class() {

$one <<= 8;
$onetwothree = 3;

// Issue 3326.
class Test
{
public const DEFAULT = 'default';
public const SOS = 'sos';
public const HELP = 'help';

protected static $thisIsAReallyLongVariableName = [];
}
Original file line number Diff line number Diff line change
Expand Up @@ -468,3 +468,13 @@ $resource = new class() {

$one <<= 8;
$onetwothree = 3;

// Issue 3326.
class Test
{
public const DEFAULT = 'default';
public const SOS = 'sos';
public const HELP = 'help';

protected static $thisIsAReallyLongVariableName = [];
}
71 changes: 27 additions & 44 deletions src/Tokenizers/PHP.php
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,29 @@ class PHP extends Tokenizer
T_TYPE_UNION => 1,
];

/**
* Contexts in which keywords should always be tokenized as T_STRING.
*
* @var array
*/
protected $tstringContexts = [
T_OBJECT_OPERATOR => true,
T_NULLSAFE_OBJECT_OPERATOR => true,
T_FUNCTION => true,
T_CLASS => true,
T_INTERFACE => true,
T_TRAIT => true,
T_EXTENDS => true,
T_IMPLEMENTS => true,
T_ATTRIBUTE => true,
T_NEW => true,
T_CONST => true,
T_NS_SEPARATOR => true,
T_USE => true,
T_NAMESPACE => true,
T_PAAMAYIM_NEKUDOTAYIM => true,
];

/**
* A cache of different token types, resolved into arrays.
*
Expand Down Expand Up @@ -1332,16 +1355,7 @@ protected function tokenize($string)
break;
}

$notMatchContext = [
T_PAAMAYIM_NEKUDOTAYIM => true,
T_OBJECT_OPERATOR => true,
T_NULLSAFE_OBJECT_OPERATOR => true,
T_NS_SEPARATOR => true,
T_NEW => true,
T_FUNCTION => true,
];

if (isset($notMatchContext[$finalTokens[$lastNotEmptyToken]['code']]) === true) {
if (isset($this->tstringContexts[$finalTokens[$lastNotEmptyToken]['code']]) === true) {
// Also not a match expression.
break;
}
Expand Down Expand Up @@ -1389,14 +1403,7 @@ protected function tokenize($string)
if ($tokenIsArray === true
&& $token[0] === T_DEFAULT
) {
$ignoreContext = [
T_OBJECT_OPERATOR => true,
T_NULLSAFE_OBJECT_OPERATOR => true,
T_NS_SEPARATOR => true,
T_PAAMAYIM_NEKUDOTAYIM => true,
];

if (isset($ignoreContext[$finalTokens[$lastNotEmptyToken]['code']]) === false) {
if (isset($this->tstringContexts[$finalTokens[$lastNotEmptyToken]['code']]) === false) {
for ($x = ($stackPtr + 1); $x < $numTokens; $x++) {
if ($tokens[$x] === ',') {
// Skip over potential trailing comma (supported in PHP).
Expand Down Expand Up @@ -1894,25 +1901,7 @@ function return types. We want to keep the parenthesis map clean,
if ($tokenIsArray === true && $token[0] === T_STRING) {
// Some T_STRING tokens should remain that way
// due to their context.
$context = [
T_OBJECT_OPERATOR => true,
T_NULLSAFE_OBJECT_OPERATOR => true,
T_FUNCTION => true,
T_CLASS => true,
T_INTERFACE => true,
T_TRAIT => true,
T_EXTENDS => true,
T_IMPLEMENTS => true,
T_ATTRIBUTE => true,
T_NEW => true,
T_CONST => true,
T_NS_SEPARATOR => true,
T_USE => true,
T_NAMESPACE => true,
T_PAAMAYIM_NEKUDOTAYIM => true,
];

if (isset($context[$finalTokens[$lastNotEmptyToken]['code']]) === true) {
if (isset($this->tstringContexts[$finalTokens[$lastNotEmptyToken]['code']]) === true) {
// Special case for syntax like: return new self
// where self should not be a string.
if ($finalTokens[$lastNotEmptyToken]['code'] === T_NEW
Expand Down Expand Up @@ -2786,13 +2775,7 @@ protected function processAdditional()
}
}

$context = [
T_OBJECT_OPERATOR => true,
T_NULLSAFE_OBJECT_OPERATOR => true,
T_NS_SEPARATOR => true,
T_PAAMAYIM_NEKUDOTAYIM => true,
];
if (isset($context[$this->tokens[$x]['code']]) === true) {
if (isset($this->tstringContexts[$this->tokens[$x]['code']]) === true) {
if (PHP_CODESNIFFER_VERBOSITY > 1) {
$line = $this->tokens[$i]['line'];
$type = $this->tokens[$i]['type'];
Expand Down
8 changes: 8 additions & 0 deletions tests/Core/Tokenizer/DefaultKeywordTest.inc
Original file line number Diff line number Diff line change
Expand Up @@ -193,3 +193,11 @@ function switchWithConstantNonDefault($i) {
return 2;
}
}

class Foo {
/* testClassConstant */
const DEFAULT = 'foo';

/* testMethodDeclaration */
public function default() {}
}
27 changes: 27 additions & 0 deletions tests/Core/Tokenizer/DefaultKeywordTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -267,9 +267,36 @@ public function dataNotDefaultKeyword()
'class-property-in-switch-case' => ['/* testClassPropertyInSwitchCase */'],
'namespaced-constant-in-switch-case' => ['/* testNamespacedConstantInSwitchCase */'],
'namespace-relative-constant-in-switch-case' => ['/* testNamespaceRelativeConstantInSwitchCase */'],

'class-constant-declaration' => ['/* testClassConstant */'],
'class-method-declaration' => [
'/* testMethodDeclaration */',
'default',
],
];

}//end dataNotDefaultKeyword()


/**
* Test a specific edge case where a scope opener would be incorrectly set.
*
* @link https://github.com/squizlabs/PHP_CodeSniffer/issues/3326
*
* @return void
*/
public function testIssue3326()
{
$tokens = self::$phpcsFile->getTokens();

$token = $this->getTargetToken('/* testClassConstant */', [T_SEMICOLON]);
$tokenArray = $tokens[$token];

$this->assertArrayNotHasKey('scope_condition', $tokenArray, 'Scope condition is set');
$this->assertArrayNotHasKey('scope_opener', $tokenArray, 'Scope opener is set');
$this->assertArrayNotHasKey('scope_closer', $tokenArray, 'Scope closer is set');

}//end testIssue3326()


}//end class

0 comments on commit 7559324

Please sign in to comment.