Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move is_token_namespaced() utility method to dedicated ContextHelper + minor simplifications #2227

Merged
merged 2 commits into from
Apr 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion WordPress/AbstractFunctionRestrictionsSniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ public function is_targetted_token( $stackPtr ) {
return false;
}

if ( $this->is_token_namespaced( $stackPtr ) === true ) {
if ( ContextHelper::is_token_namespaced( $this->phpcsFile, $stackPtr ) === true ) {
return false;
}

Expand Down
33 changes: 33 additions & 0 deletions WordPress/Helpers/ContextHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,37 @@ public static function has_object_operator_before( File $phpcsFile, $stackPtr )

return isset( Collections::objectOperators()[ $tokens[ $before ]['code'] ] );
}

/**
* Check if a particular token is prefixed with a namespace.
*
* @internal This will give a false positive if the file is not namespaced and the token is prefixed
* with `namespace\`.
*
* @since 2.1.0
* @since 3.0.0 - Moved from the Sniff class to this class.
* - The method visibility was changed from `protected` to `public static`.
*
* @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.
* @param int $stackPtr The index of the token in the stack.
*
* @return bool
*/
public static function is_token_namespaced( File $phpcsFile, $stackPtr ) {
$tokens = $phpcsFile->getTokens();
$prev = $phpcsFile->findPrevious( Tokens::$emptyTokens, ( $stackPtr - 1 ), null, true );

if ( \T_NS_SEPARATOR !== $tokens[ $prev ]['code'] ) {
return false;
}

$before_prev = $phpcsFile->findPrevious( Tokens::$emptyTokens, ( $prev - 1 ), null, true );
if ( \T_STRING !== $tokens[ $before_prev ]['code']
&& \T_NAMESPACE !== $tokens[ $before_prev ]['code']
) {
return false;
}

return true;
}
}
43 changes: 3 additions & 40 deletions WordPress/Sniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -508,43 +508,6 @@ protected function is_in_isset_or_empty( $stackPtr ) {
return false;
}

/**
* Check if a particular token is prefixed with a namespace.
*
* @internal This will give a false positive if the file is not namespaced and the token is prefixed
* with `namespace\`.
*
* @since 2.1.0
*
* @param int $stackPtr The index of the token in the stack.
*
* @return bool
*/
protected function is_token_namespaced( $stackPtr ) {
$prev = $this->phpcsFile->findPrevious( Tokens::$emptyTokens, ( $stackPtr - 1 ), null, true, null, true );

if ( false === $prev ) {
return false;
}

if ( \T_NS_SEPARATOR !== $this->tokens[ $prev ]['code'] ) {
return false;
}

$before_prev = $this->phpcsFile->findPrevious( Tokens::$emptyTokens, ( $prev - 1 ), null, true, null, true );
if ( false === $before_prev ) {
return false;
}

if ( \T_STRING !== $this->tokens[ $before_prev ]['code']
&& \T_NAMESPACE !== $this->tokens[ $before_prev ]['code']
) {
return false;
}

return true;
}

/**
* Check if a token is (part of) a parameter for a function call to a select list of functions.
*
Expand Down Expand Up @@ -614,7 +577,7 @@ protected function is_in_function_call( $stackPtr, $valid_functions, $global_fun
continue;
}

if ( $this->is_token_namespaced( $prev_non_empty ) === true ) {
if ( ContextHelper::is_token_namespaced( $this->phpcsFile, $prev_non_empty ) === true ) {
continue;
}

Expand Down Expand Up @@ -1004,7 +967,7 @@ protected function is_validated( $stackPtr, $array_keys = array(), $in_condition
continue 2;
}

if ( $this->is_token_namespaced( $i ) === true ) {
if ( ContextHelper::is_token_namespaced( $this->phpcsFile, $i ) === true ) {
// Namespaced function call.
continue 2;
}
Expand Down Expand Up @@ -1180,7 +1143,7 @@ public function is_use_of_global_constant( $stackPtr ) {
return false;
}

if ( $this->is_token_namespaced( $stackPtr ) === true ) {
if ( ContextHelper::is_token_namespaced( $this->phpcsFile, $stackPtr ) === true ) {
// Namespaced constant of the same name.
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion WordPress/Sniffs/Security/NonceVerificationSniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ private function has_nonce_check( $stackPtr ) {
continue;
}

if ( $this->is_token_namespaced( $i ) === true ) {
if ( ContextHelper::is_token_namespaced( $this->phpcsFile, $i ) === true ) {
continue;
}

Expand Down
5 changes: 3 additions & 2 deletions WordPress/Sniffs/WP/DiscouragedConstantsSniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@

namespace WordPressCS\WordPress\Sniffs\WP;

use WordPressCS\WordPress\AbstractFunctionParameterSniff;
use PHP_CodeSniffer\Util\Tokens;
use PHPCSUtils\Tokens\Collections;
use PHPCSUtils\Utils\MessageHelper;
use PHPCSUtils\Utils\PassedParameters;
use PHPCSUtils\Utils\Scopes;
use PHPCSUtils\Utils\TextStrings;
use WordPressCS\WordPress\AbstractFunctionParameterSniff;
use WordPressCS\WordPress\Helpers\ContextHelper;

/**
* Warns against usage of discouraged WP CONSTANTS and recommends alternatives.
Expand Down Expand Up @@ -140,7 +141,7 @@ public function process_arbitrary_tstring( $stackPtr ) {
return;
}

if ( $this->is_token_namespaced( $stackPtr ) === true ) {
if ( ContextHelper::is_token_namespaced( $this->phpcsFile, $stackPtr ) === true ) {
// Namespaced constant of the same name.
return;
}
Expand Down
7 changes: 7 additions & 0 deletions WordPress/Tests/WP/DiscouragedFunctionsUnitTest.inc
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,10 @@ wp_reset_query(); // Warning, use wp_reset_postdata instead.
$obj->query_posts(); // OK, not the global function.
MyClass::wp_reset_query(); // OK, not the global function.
$obj?->query_posts(); // OK, not the global function.

// Ensure the sniff doesn't act on namespaced calls.
MyNamespace\query_posts(); // OK, not the global function.
namespace\query_posts(); // OK, not the global function.

// ... but does act on fully qualified function calls.
\query_posts(); // Warning.
6 changes: 4 additions & 2 deletions WordPress/Tests/WP/DiscouragedFunctionsUnitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
*
* @covers \WordPressCS\WordPress\AbstractFunctionRestrictionsSniff
* @covers \WordPressCS\WordPress\Helpers\ContextHelper::has_object_operator_before
* @covers \WordPressCS\WordPress\Helpers\ContextHelper::is_token_namespaced
* @covers \WordPressCS\WordPress\Sniffs\WP\DiscouragedFunctionsSniff
*/
final class DiscouragedFunctionsUnitTest extends AbstractSniffUnitTest {
Expand All @@ -41,8 +42,9 @@ public function getErrorList() {
*/
public function getWarningList() {
return array(
3 => 1,
4 => 1,
3 => 1,
4 => 1,
20 => 1,
);
}
}