Skip to content

Commit

Permalink
Move is_class_object_call() utility method to dedicated `ContextHel…
Browse files Browse the repository at this point in the history
…per`

The `is_class_object_call()` utility method is only used by a small set of sniffs, so is better placed in a dedicated class.

This commit moves the `is_class_object_call()` method to the new `WordPressCS\WordPress\Helpers\ContextHelper` class and starts using that class in the relevant sniffs.

The method has also been renamed to `has_object_operator_before()` as it doesn't actually check if something is a (method) _call_, just that something OO (method, constant, property) is being accessed.

Related to 1465

This method is tested via the `WordPress.WP.DiscouragedFunctions` sniff.
  • Loading branch information
jrfnl committed Apr 18, 2023
1 parent de872bb commit 34f1ada
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 36 deletions.
3 changes: 2 additions & 1 deletion WordPress/AbstractFunctionRestrictionsSniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

use PHP_CodeSniffer\Util\Tokens;
use PHPCSUtils\Utils\MessageHelper;
use WordPressCS\WordPress\Helpers\ContextHelper;
use WordPressCS\WordPress\Helpers\RulesetPropertyHelper;
use WordPressCS\WordPress\Sniff;

Expand Down Expand Up @@ -219,7 +220,7 @@ public function is_targetted_token( $stackPtr ) {
}

// Exclude function definitions, class methods, and namespaced calls.
if ( $this->is_class_object_call( $stackPtr ) === true ) {
if ( ContextHelper::has_object_operator_before( $this->phpcsFile, $stackPtr ) === true ) {
return false;
}

Expand Down
59 changes: 59 additions & 0 deletions WordPress/Helpers/ContextHelper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php
/**
* WordPress Coding Standard.
*
* @package WPCS\WordPressCodingStandards
* @link https://github.com/WordPress/WordPress-Coding-Standards
* @license https://opensource.org/licenses/MIT MIT
*/

namespace WordPressCS\WordPress\Helpers;

use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Util\Tokens;

/**
* Helper utilities for checking the context in which a token is used.
*
* ---------------------------------------------------------------------------------------------
* This class is only intended for internal use by WordPressCS and is not part of the public API.
* This also means that it has no promise of backward compatibility. Use at your own risk.
* ---------------------------------------------------------------------------------------------
*
* @package WPCS\WordPressCodingStandards
* @since 3.0.0 The methods in this class were previously contained in the
* `WordPressCS\WordPress\Sniff` class and have been moved here.
*/
final class ContextHelper {

/**
* Check if a particular token acts - statically or non-statically - on an object.
*
* @internal Note: this may still mistake a namespaced function imported via a `use` statement for
* a global function!
*
* @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 has_object_operator_before( File $phpcsFile, $stackPtr ) {
$before = $phpcsFile->findPrevious( Tokens::$emptyTokens, ( $stackPtr - 1 ), null, true, null, true );
if ( false === $before ) {
return false;
}

$tokens = $phpcsFile->getTokens();
if ( \T_OBJECT_OPERATOR !== $tokens[ $before ]['code']
&& \T_DOUBLE_COLON !== $tokens[ $before ]['code']
) {
return false;
}

return true;
}
}
33 changes: 3 additions & 30 deletions WordPress/Sniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use PHPCSUtils\Utils\PassedParameters;
use PHPCSUtils\Utils\Scopes;
use PHPCSUtils\Utils\TextStrings;
use WordPressCS\WordPress\Helpers\ContextHelper;
use WordPressCS\WordPress\Helpers\VariableHelper;

/**
Expand Down Expand Up @@ -507,34 +508,6 @@ protected function is_in_isset_or_empty( $stackPtr ) {
return false;
}

/**
* Check if a particular token is a (static or non-static) call to a class method or property.
*
* @internal Note: this may still mistake a namespaced function imported via a `use` statement for
* a global function!
*
* @since 2.1.0
*
* @param int $stackPtr The index of the token in the stack.
*
* @return bool
*/
protected function is_class_object_call( $stackPtr ) {
$before = $this->phpcsFile->findPrevious( Tokens::$emptyTokens, ( $stackPtr - 1 ), null, true, null, true );

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

if ( \T_OBJECT_OPERATOR !== $this->tokens[ $before ]['code']
&& \T_DOUBLE_COLON !== $this->tokens[ $before ]['code']
) {
return false;
}

return true;
}

/**
* Check if a particular token is prefixed with a namespace.
*
Expand Down Expand Up @@ -637,7 +610,7 @@ protected function is_in_function_call( $stackPtr, $valid_functions, $global_fun
/*
* Now, make sure it is a global function.
*/
if ( $this->is_class_object_call( $prev_non_empty ) === true ) {
if ( ContextHelper::has_object_operator_before( $this->phpcsFile, $prev_non_empty ) === true ) {
continue;
}

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

if ( $this->is_class_object_call( $i ) === true ) {
if ( ContextHelper::has_object_operator_before( $this->phpcsFile, $i ) === true ) {
// Method call.
continue 2;
}
Expand Down
3 changes: 2 additions & 1 deletion WordPress/Sniffs/Security/NonceVerificationSniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

use PHP_CodeSniffer\Util\Tokens;
use PHPCSUtils\Utils\MessageHelper;
use WordPressCS\WordPress\Helpers\ContextHelper;
use WordPressCS\WordPress\Helpers\RulesetPropertyHelper;
use WordPressCS\WordPress\Helpers\VariableHelper;
use WordPressCS\WordPress\Sniff;
Expand Down Expand Up @@ -269,7 +270,7 @@ private function has_nonce_check( $stackPtr ) {
/*
* Now, make sure it is a call to a global function.
*/
if ( $this->is_class_object_call( $i ) === true ) {
if ( ContextHelper::has_object_operator_before( $this->phpcsFile, $i ) === true ) {
continue;
}

Expand Down
3 changes: 2 additions & 1 deletion WordPress/Sniffs/WP/GlobalVariablesOverrideSniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use PHPCSUtils\Utils\Parentheses;
use PHPCSUtils\Utils\Scopes;
use PHPCSUtils\Utils\TextStrings;
use WordPressCS\WordPress\Helpers\ContextHelper;
use WordPressCS\WordPress\Helpers\IsUnitTestTrait;
use WordPressCS\WordPress\Helpers\VariableHelper;
use WordPressCS\WordPress\Helpers\WPGlobalVariablesHelper;
Expand Down Expand Up @@ -393,7 +394,7 @@ protected function process_global_statement( $stackPtr, $in_function_scope ) {
}

// Don't throw false positives for static class properties.
if ( $this->is_class_object_call( $ptr ) === true ) {
if ( ContextHelper::has_object_operator_before( $this->phpcsFile, $ptr ) === true ) {
continue;
}

Expand Down
9 changes: 8 additions & 1 deletion WordPress/Tests/WP/DiscouragedFunctionsUnitTest.inc
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
<?php

query_posts(); // Warning, use WP_Query instead.

wp_reset_query(); // Warning, use wp_reset_postdata instead.

/*
* Tests which are more specifically for the AbstractFunctionRestrictionsSniff class and Helper methods.
*/

// Ensure the sniff doesn't act on methods calls.
$obj->query_posts(); // OK, not the global function.
MyClass::wp_reset_query(); // OK, not the global function.
4 changes: 2 additions & 2 deletions WordPress/Tests/WP/DiscouragedFunctionsUnitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
* @since 0.13.0 Class name changed: this class is now namespaced.
*
* @covers \WordPressCS\WordPress\AbstractFunctionRestrictionsSniff
* @covers \WordPressCS\WordPress\Helpers\ContextHelper::has_object_operator_before
* @covers \WordPressCS\WordPress\Sniffs\WP\DiscouragedFunctionsSniff
*/
final class DiscouragedFunctionsUnitTest extends AbstractSniffUnitTest {
Expand All @@ -41,8 +42,7 @@ public function getErrorList() {
public function getWarningList() {
return array(
3 => 1,
5 => 1,
4 => 1,
);
}

}

0 comments on commit 34f1ada

Please sign in to comment.