Skip to content

Commit f668905

Browse files
committed
AbstractFunctionParameterSniff: fix first class callables and function imports
The `AbstractFunctionParameterSniff` class was incorrectly flagging first class callables and function imports as a function call without parameters. This commit fixes this behavior by introducing the `AbstractFunctionParameterSniff::is_targetted_token()` method. This method calls the parent method and then performs two additional checks to make sniffs extending this class ignore first class callables and function imports. Since there are no tests for the abstract classes and the plan is to replace those classes with similar PHPCSUtils classes, I opted to add a few tests to the `I18nTextDomainFixer` tests that generate false positives before the changes implemented in this commit.
1 parent eb39475 commit f668905

File tree

2 files changed

+59
-0
lines changed

2 files changed

+59
-0
lines changed

WordPress/AbstractFunctionParameterSniff.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
namespace WordPressCS\WordPress;
1111

12+
use PHP_CodeSniffer\Util\Tokens;
1213
use PHPCSUtils\Utils\PassedParameters;
1314
use WordPressCS\WordPress\AbstractFunctionRestrictionsSniff;
1415

@@ -77,6 +78,49 @@ public function process_matched_token( $stackPtr, $group_name, $matched_content
7778
}
7879
}
7980

81+
/**
82+
* Verify if the current token is a function call. Behaves like the parent method, except that
83+
* it also returns false if the function name is used in the context of a first class callable
84+
* or an import.
85+
*
86+
* @param int $stackPtr The position of the current token in the stack.
87+
*
88+
* @return bool
89+
*/
90+
public function is_targetted_token( $stackPtr ) {
91+
$is_target_token = parent::is_targetted_token( $stackPtr );
92+
93+
if ( ! $is_target_token ) {
94+
return false;
95+
}
96+
97+
$ignore = Tokens::$emptyTokens;
98+
$ignore[ \T_BITWISE_AND ] = \T_BITWISE_AND;
99+
$prev = $this->phpcsFile->findPrevious( $ignore, ( $stackPtr - 1 ), null, true );
100+
$next = $this->phpcsFile->findNext( Tokens::$emptyTokens, ( $stackPtr + 1 ), null, true );
101+
102+
// Function import.
103+
if ( ( \T_STRING === $this->tokens[ $prev ]['code'] && 'function' === $this->tokens[ $prev ]['content'] )
104+
&& ( \T_AS === $this->tokens[ $next ]['code'] || \T_SEMICOLON === $this->tokens[ $next ]['code'] )
105+
) {
106+
return false;
107+
}
108+
109+
$nextNonEmpty = $this->phpcsFile->findNext(
110+
Tokens::$emptyTokens,
111+
( $next + 1 ),
112+
null,
113+
true
114+
);
115+
116+
// First class callable.
117+
if ( \T_ELLIPSIS === $this->tokens[ $nextNonEmpty ]['code'] ) {
118+
return false;
119+
}
120+
121+
return true;
122+
}
123+
80124
/**
81125
* Process the parameters of a matched function.
82126
*
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
// phpcs:set WordPress.Utils.I18nTextDomainFixer old_text_domain
4+
// phpcs:set WordPress.Utils.I18nTextDomainFixer new_text_domain my-text-domain
5+
6+
/*
7+
* Test that AbstractFunctionParameterSniff does not treat first class callables and function
8+
* imports as a function call without parameters. This test is added here as there are no dedicated
9+
* tests for the WPCS abstract classes. The WPCS abstract classes will be replaced with PHPCSUtils
10+
* similar classes in the future, so it is not worth creating dedicated tests at this point.
11+
*/
12+
13+
use function __;
14+
use function __ as my_function;
15+
add_action('my_action', __(...));

0 commit comments

Comments
 (0)