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

Improve sniff handling of modern PHP code #764

Open
jrfnl opened this issue Jan 1, 2017 · 9 comments
Open

Improve sniff handling of modern PHP code #764

jrfnl opened this issue Jan 1, 2017 · 9 comments

Comments

@jrfnl
Copy link
Member

jrfnl commented Jan 1, 2017

While WP still has a minimum requirement of PHP 5.2 and a lot of related projects code accordingly, there are also numerous projects out there which have set their plugin/theme minimum requirement at PHP 5.3 or higher.

Most sniffs currently don't take things like namespaces into account so the below code would trigger an error (even though the fwrite function in this case is namespaced).

While this may not be the best example (or good practice in the first place), I would like to suggest we review code to see if we can make it more forward compatible with modern PHP code.

namespace MyNamespace;

function fwrite() {
	// A compat layer or something.
}

class My_Class {
	function do_something() {
		fwrite( $param );
	}
}
@jrfnl
Copy link
Member Author

jrfnl commented Jan 2, 2017

Another typical one which is currently not or hardly taken into account: T_HEREDOC

@jrfnl
Copy link
Member Author

jrfnl commented Mar 22, 2017

Let's try & keep track of the reviews done:

Globally checked (I might well have missed something) that sniffs allow correctly for:

  • short array tokens
  • closures/anonymous functions
  • anonymous classes
  • interfaces
  • traits
  • try/catch/finally constructs
  • __NAMESPACE__, __TRAIT__, __DIR__ magic constants
  • T_NOWDOC and related tokens
  • T_HEREDOC and related tokens
  • namespaces
  • use statements
  • type hints
  • yield (for generators) and yield from
  • ternary without middle $x ? : $y
  • new operators: T_POW, T_POW_EQUAL, T_ELLIPSIS, T_SPACESHIP, T_COALESCE, T_COALESCE_EQUAL

N.B.: I don't "own" this ticket. Everyone is warmly invited to contribute, both in ideas of what to check for as well as doing the reviews!

@dingo-d
Copy link
Member

dingo-d commented Nov 23, 2018

Just a check: would this handle things like

namespace Custom_Namespace;

class My_Class {

  public function get_posts() {
    $args = array(
      'post_type'   => 'post',
      'post_status' => 'publish',
      'perm'        => 'readable',
    );
    
    $query = new WP_Query( $args ); // This would trigger error, since it's not called from global namespace like \WP_Query.
    
    if ( $query->have_posts() ) {
      while ( $query->have_posts() ) {
        $query->the_post();
      }
      wp_reset_postdata();
    } else {
      // no posts found
    }
  }

}

Basically any WP class called within a namespace should be called from a global namespace \WP_Query in the above example.

@jrfnl
Copy link
Member Author

jrfnl commented Nov 23, 2018

@dingo-d

Basically any WP class called within a namespace should be called from a global namespace \WP_Query in the above example.

Or should have a use statement ;-)

That's not actually what this issue is about. The current issue is about making the existing sniffs more resilient when they encounter modern PHP code, including prevent false positives/negatives.

I.e. say there would be a sniff which would detect the use of WP_Query, that sniff should not trigger on your code example as the WP_Query used in your code is not the WP class, but a custom Custom_Namespace\WP_Query class.

There is currently no sniff available in WPCS which checks that WP native classes when used in a namespaced context are prefixed with a \ or have a use statement.
I think it could be a valid feature request for such a sniff to be created, but that should be discussed in another issue.

In the mean time, there might be a sniff in the Slevomat standard which could help detect these issues.

@dingo-d
Copy link
Member

dingo-d commented Nov 23, 2018

There is currently no sniff available in WPCS which checks that WP native classes when used in a namespaced context are prefixed with a \ or have a use statement.
I think it could be a valid feature request for such a sniff to be created, but that should be discussed in another issue.

Yeah, this was basically what I was thinking about, but I didn't want to create an issue if there is no need for it 🙂

Thanks for clarifying it out 👍

@jrfnl
Copy link
Member Author

jrfnl commented Aug 18, 2023

All sniffs have been reviewed and fixed to support modern PHP in as far as my imagination reached.

There is still a known issue with resolving namespaces/use statements. That is expected to be fixed via a future PHPCSUtils version and abstract sniffs provided by PHPCSUtils.

@westonruter
Copy link
Member

Speaking of use statements, we just noticed in WordPress/plugin-check#334 (comment) that WPCS spacing isn't currently enforced around use. Core always includes a space after use, so WPCS should be making this change:

  add_action(
  	'populate_options',
- 	static function () use( $permalink_structure ) {
+ 	static function () use ( $permalink_structure ) {
  		add_option( 'permalink_structure', $permalink_structure );
  	}
  );

@jrfnl
Copy link
Member Author

jrfnl commented Dec 11, 2023

@westonruter Interesting. In my original tests that resulted in a duplicate error being thrown - both from Squiz.Functions.MultiLineFunctionDeclaration.SpaceAfterUse as well as Generic.WhiteSpace.LanguageConstructSpacing, but with your code sample, no error is thrown from the Generic.WhiteSpace.LanguageConstructSpacing.

Looks like the duplication exists only when there is too much whitespace, not when there is not enough.

This is related to

<!-- Prevent duplicate message. This is already checked by the Generic.WhiteSpace.LanguageConstructSpacing sniff. -->
<rule ref="Squiz.Functions.MultiLineFunctionDeclaration.SpaceAfterUse">
<severity>0</severity>
</rule>
, which was introduced in #2328.

I suppose we can remove that exclusion in favour of sometimes receiving duplicate messages.

jrfnl added a commit that referenced this issue Dec 11, 2023
Turns out the exclusion is a little too aggresive.
The `Generic.WhiteSpace.LanguageConstructSpacing` _will_ throw an error when there is too much whitespace, but not when there is no whitespace and the next thing is an open parenthesis.

By removing the exclusion, an error will now (correctly) be thrown when there is no whitespace between a closure `use` keyword and the open parenthesis.

It also means that where there is _too much_ whitespace between the keyword and the open parenthesis, two errors will be thrown, one from the `Generic.WhiteSpace.LanguageConstructSpacing` sniff and one from the `Squiz.Functions.MultiLineFunctionDeclaration` sniff.

Well, so be it. As both sniffs expect the same thing, this shouldn't lead to fixer conflicts anyhow.

See #764 (comment)
@jrfnl
Copy link
Member Author

jrfnl commented Dec 11, 2023

@westonruter See #2415

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants