Skip to content

Commit

Permalink
UseStatementHelper optimizations
Browse files Browse the repository at this point in the history
  • Loading branch information
kukulich committed Mar 9, 2024
1 parent 6ea0278 commit 5cac991
Show file tree
Hide file tree
Showing 12 changed files with 94 additions and 41 deletions.
3 changes: 1 addition & 2 deletions SlevomatCodingStandard/Helpers/ClassHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
namespace SlevomatCodingStandard\Helpers;

use PHP_CodeSniffer\Files\File;
use function array_merge;
use function array_reverse;
use function sprintf;
use const T_ANON_CLASS;
Expand Down Expand Up @@ -112,7 +111,7 @@ public static function getTraitUsePointers(File $phpcsFile, int $classPointer):
private static function getAllClassPointers(File $phpcsFile): array
{
$lazyValue = static function () use ($phpcsFile): array {
return TokenHelper::findNextAll($phpcsFile, array_merge(TokenHelper::$typeKeywordTokenCodes, [T_ANON_CLASS]), 0);
return TokenHelper::findNextAll($phpcsFile, TokenHelper::$typeWithAnonymousClassKeywordTokenCodes, 0);
};

return SniffLocalCache::getAndSetIfNotCached($phpcsFile, 'classPointers', $lazyValue);
Expand Down
10 changes: 10 additions & 0 deletions SlevomatCodingStandard/Helpers/TokenHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use function array_key_exists;
use function array_merge;
use function count;
use const T_ANON_CLASS;
use const T_ARRAY;
use const T_ARRAY_HINT;
use const T_BREAK;
Expand Down Expand Up @@ -75,6 +76,15 @@ class TokenHelper
T_ENUM,
];

/** @var array<int, (int|string)> */
public static $typeWithAnonymousClassKeywordTokenCodes = [
T_CLASS,
T_ANON_CLASS,
T_TRAIT,
T_INTERFACE,
T_ENUM,
];

/** @var array<int, (int|string)> */
public static $ineffectiveTokenCodes = [
T_WHITESPACE,
Expand Down
72 changes: 58 additions & 14 deletions SlevomatCodingStandard/Helpers/UseStatementHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,20 @@
namespace SlevomatCodingStandard\Helpers;

use PHP_CodeSniffer\Files\File;
use function array_key_exists;
use function array_merge;
use function array_reverse;
use function count;
use function current;
use function in_array;
use const T_ANON_CLASS;
use function strtolower;
use const T_AS;
use const T_CLOSE_CURLY_BRACKET;
use const T_COMMA;
use const T_DECLARE;
use const T_FUNCTION;
use const T_NAMESPACE;
use const T_OPEN_CURLY_BRACKET;
use const T_OPEN_PARENTHESIS;
use const T_OPEN_TAG;
use const T_OPEN_USE_GROUP;
Expand All @@ -25,29 +30,68 @@
class UseStatementHelper
{

public static function isAnonymousFunctionUse(File $phpcsFile, int $usePointer): bool
public static function isImportUse(File $phpcsFile, int $usePointer): bool
{
$tokens = $phpcsFile->getTokens();
$nextPointer = TokenHelper::findNextEffective($phpcsFile, $usePointer + 1);
$nextToken = $tokens[$nextPointer];

return $nextToken['code'] === T_OPEN_PARENTHESIS;
// Anonymous function use
if ($tokens[$nextPointer]['code'] === T_OPEN_PARENTHESIS) {
return false;
}

if (
$tokens[$nextPointer]['code'] === T_STRING
&& in_array(strtolower($tokens[$nextPointer]['content']), ['function', 'const'], true)
) {
return true;
}

$previousPointer = TokenHelper::findPrevious(
$phpcsFile,
[T_OPEN_TAG, T_DECLARE, T_NAMESPACE, T_OPEN_CURLY_BRACKET, T_CLOSE_CURLY_BRACKET],
$usePointer
);

if (in_array($tokens[$previousPointer]['code'], [T_OPEN_TAG, T_DECLARE, T_NAMESPACE], true)) {
return true;
}

if (array_key_exists('scope_condition', $tokens[$previousPointer])) {
$scopeConditionPointer = $tokens[$previousPointer]['scope_condition'];

if (
$tokens[$previousPointer]['code'] === T_OPEN_CURLY_BRACKET
&& in_array($tokens[$scopeConditionPointer]['code'], TokenHelper::$typeWithAnonymousClassKeywordTokenCodes, true)
) {
return false;
}

// Trait use after another trait use
if ($tokens[$scopeConditionPointer]['code'] === T_USE) {
return false;
}

// Trait use after method or import use after function
if ($tokens[$scopeConditionPointer]['code'] === T_FUNCTION) {
return ClassHelper::getClassPointer($phpcsFile, $usePointer) === null;
}
}

return true;
}

public static function isTraitUse(File $phpcsFile, int $usePointer): bool
{
$typePointer = TokenHelper::findPrevious($phpcsFile, array_merge(TokenHelper::$typeKeywordTokenCodes, [T_ANON_CLASS]), $usePointer);
if ($typePointer !== null) {
$tokens = $phpcsFile->getTokens();
$typeToken = $tokens[$typePointer];
$openerPointer = $typeToken['scope_opener'];
$closerPointer = $typeToken['scope_closer'];
$tokens = $phpcsFile->getTokens();
$nextPointer = TokenHelper::findNextEffective($phpcsFile, $usePointer + 1);

return $usePointer > $openerPointer && $usePointer < $closerPointer
&& !self::isAnonymousFunctionUse($phpcsFile, $usePointer);
// Anonymous function use
if ($tokens[$nextPointer]['code'] === T_OPEN_PARENTHESIS) {
return false;
}

return false;
return !self::isImportUse($phpcsFile, $usePointer);
}

public static function getAlias(File $phpcsFile, int $usePointer): ?string
Expand Down Expand Up @@ -200,7 +244,7 @@ private static function getUseStatementPointers(File $phpcsFile, int $openTagPoi
continue;
}

if (self::isAnonymousFunctionUse($phpcsFile, $pointer)) {
if (!self::isImportUse($phpcsFile, $pointer)) {
$pointer++;
continue;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,10 @@
use SlevomatCodingStandard\Helpers\TokenHelper;
use SlevomatCodingStandard\Helpers\UseStatementHelper;
use function array_key_exists;
use function array_merge;
use function in_array;
use function sprintf;
use function str_repeat;
use const T_ABSTRACT;
use const T_ANON_CLASS;
use const T_AS;
use const T_ATTRIBUTE_END;
use const T_CLOSE_CURLY_BRACKET;
Expand Down Expand Up @@ -52,8 +50,7 @@ class ClassMemberSpacingSniff implements Sniff
*/
public function register(): array
{
/** @phpstan-var array<int, (int|string)> */
return array_merge(TokenHelper::$typeKeywordTokenCodes, [T_ANON_CLASS]);
return TokenHelper::$typeWithAnonymousClassKeywordTokenCodes;
}

/**
Expand Down
6 changes: 4 additions & 2 deletions SlevomatCodingStandard/Sniffs/Files/LineLengthSniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,11 @@ private function checkLineLength(File $phpcsFile, int $pointer): void

if ($this->ignoreImports) {
$usePointer = UseStatementHelper::getUseStatementPointer($phpcsFile, $pointer - 1);
if (is_int($usePointer)
if (
is_int($usePointer)
&& $tokens[$usePointer]['line'] === $tokens[$pointer]['line']
&& !UseStatementHelper::isTraitUse($phpcsFile, $usePointer)) {
&& UseStatementHelper::isImportUse($phpcsFile, $usePointer)
) {
return;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,7 @@ public function register(): array
*/
public function process(File $phpcsFile, $usePointer): void
{
if (
UseStatementHelper::isAnonymousFunctionUse($phpcsFile, $usePointer)
|| UseStatementHelper::isTraitUse($phpcsFile, $usePointer)
) {
if (!UseStatementHelper::isImportUse($phpcsFile, $usePointer)) {
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,7 @@ public function register(): array
*/
public function process(File $phpcsFile, $usePointer): void
{
if (
UseStatementHelper::isAnonymousFunctionUse($phpcsFile, $usePointer)
|| UseStatementHelper::isTraitUse($phpcsFile, $usePointer)
) {
if (!UseStatementHelper::isImportUse($phpcsFile, $usePointer)) {
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,7 @@ public function register(): array
*/
public function process(File $phpcsFile, $usePointer): void
{
if (
UseStatementHelper::isAnonymousFunctionUse($phpcsFile, $usePointer)
|| UseStatementHelper::isTraitUse($phpcsFile, $usePointer)
) {
if (!UseStatementHelper::isImportUse($phpcsFile, $usePointer)) {
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,7 @@ public function register(): array
*/
public function process(File $phpcsFile, $usePointer): void
{
if (
UseStatementHelper::isAnonymousFunctionUse($phpcsFile, $usePointer)
|| UseStatementHelper::isTraitUse($phpcsFile, $usePointer)
) {
if (!UseStatementHelper::isImportUse($phpcsFile, $usePointer)) {
return;
}

Expand Down
8 changes: 6 additions & 2 deletions tests/Helpers/UseStatementHelperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,25 @@ public function testIsAnonymousFunctionUse(): void
{
$phpcsFile = $this->getCodeSnifferFile(__DIR__ . '/data/anonymousFunction.php');
$usePointer = TokenHelper::findNext($phpcsFile, T_USE, 0);
self::assertTrue(UseStatementHelper::isAnonymousFunctionUse($phpcsFile, $usePointer));
self::assertFalse(UseStatementHelper::isImportUse($phpcsFile, $usePointer));
}

public function testIsNotAnonymousFunctionUse(): void
{
$phpcsFile = $this->getCodeSnifferFile(__DIR__ . '/data/useStatements.php');
$usePointer = TokenHelper::findNext($phpcsFile, T_USE, 0);
self::assertFalse(UseStatementHelper::isAnonymousFunctionUse($phpcsFile, $usePointer));
self::assertTrue(UseStatementHelper::isImportUse($phpcsFile, $usePointer));
}

public function testIsTraitUse(): void
{
$phpcsFile = $this->getCodeSnifferFile(__DIR__ . '/data/classWithTrait.php');
$usePointer = TokenHelper::findNext($phpcsFile, T_USE, 0);
self::assertTrue(UseStatementHelper::isTraitUse($phpcsFile, $usePointer));

$phpcsFile = $this->getCodeSnifferFile(__DIR__ . '/data/classWithTrait.php');
$usePointer = TokenHelper::findNext($phpcsFile, T_USE, $usePointer + 1);
self::assertTrue(UseStatementHelper::isTraitUse($phpcsFile, $usePointer));
}

public function testIsTraitUseInAnonymousClass(): void
Expand Down
8 changes: 7 additions & 1 deletion tests/Helpers/data/classWithTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
class Foo
{

use BarTrait;
use BarTrait {
BarTrait::foo as private;
}

use FooTrait {
FooTrait::bar as private;
}

}
3 changes: 3 additions & 0 deletions tests/Helpers/data/useStatements.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ function () use ($test) {

};

function whatever() {
}

use Zero;

class MyClass
Expand Down

0 comments on commit 5cac991

Please sign in to comment.