diff --git a/CodeSniffer/Standards/Squiz/Sniffs/Classes/SelfMemberReferenceSniff.php b/CodeSniffer/Standards/Squiz/Sniffs/Classes/SelfMemberReferenceSniff.php index e7ffea88bd..57a73e274b 100644 --- a/CodeSniffer/Standards/Squiz/Sniffs/Classes/SelfMemberReferenceSniff.php +++ b/CodeSniffer/Standards/Squiz/Sniffs/Classes/SelfMemberReferenceSniff.php @@ -77,10 +77,13 @@ protected function processTokenWithinScope(PHP_CodeSniffer_File $phpcsFile, $sta // Make sure this is another class reference. $declarationName = $phpcsFile->getDeclarationName($currScope); if ($declarationName === $tokens[$className]['content']) { - // Class name is the same as the current class. - $error = 'Must use "self::" for local static member reference'; - $phpcsFile->addError($error, $className, 'NotUsed'); - return; + // Class name is the same as the current class, which is not allowed + // except if being used inside a closure. + if ($phpcsFile->hasCondition($stackPtr, T_CLOSURE) === false) { + $error = 'Must use "self::" for local static member reference'; + $phpcsFile->addError($error, $className, 'NotUsed'); + return; + } } } diff --git a/CodeSniffer/Standards/Squiz/Tests/Classes/SelfMemberReferenceUnitTest.inc b/CodeSniffer/Standards/Squiz/Tests/Classes/SelfMemberReferenceUnitTest.inc index c7eeaa54de..460794c56d 100644 --- a/CodeSniffer/Standards/Squiz/Tests/Classes/SelfMemberReferenceUnitTest.inc +++ b/CodeSniffer/Standards/Squiz/Tests/Classes/SelfMemberReferenceUnitTest.inc @@ -45,4 +45,23 @@ class SelfMemberReferenceUnitTestExample } +class MyClass { + + public static function test($value) { + echo "$value\n"; + } + + public static function walk() { + $callback = function($value, $key) { + // This is valid because you cant use self:: in a closure + MyClass::test($value); + }; + + $array = array(1,2,3); + array_walk($array, $callback); + } +} + +MyClass::walk(); + ?> \ No newline at end of file diff --git a/CodeSniffer/Tokenizers/PHP.php b/CodeSniffer/Tokenizers/PHP.php index cd3d59ec29..990b6d93ad 100644 --- a/CodeSniffer/Tokenizers/PHP.php +++ b/CodeSniffer/Tokenizers/PHP.php @@ -451,10 +451,23 @@ public function processAdditional(&$tokens, $eolChar) if ($tokens[$x]['code'] === T_OPEN_PARENTHESIS) { $tokens[$i]['code'] = T_CLOSURE; + $tokens[$i]['type'] = 'T_CLOSURE'; if (PHP_CODESNIFFER_VERBOSITY > 1) { $line = $tokens[$i]['line']; echo "\t* token $i on line $line changed from T_FUNCTION to T_CLOSURE".PHP_EOL; } + + for ($x = ($tokens[$i]['scope_opener'] + 1); $x < $tokens[$i]['scope_closer']; $x++) { + if (isset($tokens[$x]['conditions'][$i]) === false) { + continue; + } + + $tokens[$x]['conditions'][$i] = T_CLOSURE; + if (PHP_CODESNIFFER_VERBOSITY > 1) { + $type = $tokens[$x]['type']; + echo "\t\t* cleaned $x ($type) *".PHP_EOL; + } + } } continue; diff --git a/package.xml b/package.xml index 604bdf63a4..6911cb59cc 100644 --- a/package.xml +++ b/package.xml @@ -44,6 +44,8 @@ http://pear.php.net/dtd/package-2.0.xsd"> - Squiz FileCommentSniff now enforces rule that package names cannot start with the word Squiz - Fixed issue in Squiz FileCommentSniff where suggested package name was the same as the incorrect package name - Fixed some issues with Squiz ArrayDeclarationSniff when using function calls in array values + - Fixed bug #18465 : "self::" does not work in lambda functions + -- Also corrects conversion of T_FUNCTION tokens to T_CLOSURE, which was not fixing token condition arrays