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

PSR2.ControlStructure.SwitchDeclaration shouldn't check indent of curly brace closers #857

Closed
dregad opened this issue Jan 10, 2016 · 6 comments

Comments

@dregad
Copy link

dregad commented Jan 10, 2016

Greetings,

I was trying to use phpcbf to fix issues detected by codesniffer in ADOdb library (following PSR-2 standard). The tool seems to go into a loop, and errors out after 50 iterations without fixing anything:

Processing perf-postgres.inc.php [PHP => 902 tokens in 154 lines]... DONE in 71ms (138 fixable violations)
        => Fixing file: 1/138 violations remaining [made 50 passes]... ERROR in 3.6 secs

After some trial and error (applying each sniff individually), I finally managed to isolate the problem to the following code (from https://github.com/ADOdb/ADOdb/blob/master/perf/perf-postgres.inc.php#L112):

<?php
switch ($mode) {
    // case statements removed
    default            :
        {
        ADOConnection::outp(sprintf("<p>%s: '%s' using of undefined mode '%s'</p>", __CLASS__, 'optimizeTable', $mode));
        return false;
    }
}

It is now easy to see that the problem is caused by use of curly braces in the default case, as shown in phpcbf output, and I assume that the fixer can't do it's work due to a conflict caused by the error at line 11.

--------------------------------------------------------------------------------------------
FOUND 2 ERRORS AFFECTING 2 LINES
--------------------------------------------------------------------------------------------
 11 | ERROR | [ ] DEFAULT statements must be defined using a colon
 15 | ERROR | [x] Terminating statement must be indented to the same level as the CASE body
--------------------------------------------------------------------------------------------
PHPCBF CAN FIX THE 1 MARKED SNIFF VIOLATIONS AUTOMATICALLY
--------------------------------------------------------------------------------------------

The problem is that phpcbf does not give a clear indication about what is actually causing the error, and when running it against the original file, the 2 lines above are drown in the midst of 180 errors and warnings, making it difficult and time-consuming to identify the root cause.

Hopefully you can find a way to improve this in a future version.

Many thanks for this excellent software !

@aik099
Copy link
Contributor

aik099 commented Jan 10, 2016

Is the syntax with curly braces inside in default even valid?

@dregad
Copy link
Author

dregad commented Jan 10, 2016

Define valid 😉

It may not make sense, but it's syntactically correct... after all you can put a code block anywhere, e.g.

if ($blah) {
    { print 'hello world'; }
}

@aik099
Copy link
Contributor

aik099 commented Jan 10, 2016

By valid I mean:

  • no syntax error
  • works in every PHP version
  • is mentioned in PHP documentation

@dregad
Copy link
Author

dregad commented Jan 10, 2016

Perfectly valid and documented here http://php.net/manual/en/control-structures.intro.php

statements can be grouped into a statement-group by encapsulating a group of statements with curly braces.

For the record, this code has been there and working just fine since PHP 3.x, and I've used it up to 5.6.

@gsherwood gsherwood changed the title phpcbf fails to fix violations PSR2.ControlStructure.SwitchDeclaration shouldn't check indent of curly brace closers Jan 12, 2016
gsherwood added a commit that referenced this issue Jan 12, 2016
@gsherwood
Copy link
Member

There were actually a couple of problems here.

The first was that the PSR2 sniff was always going to conflict with the Generic ScopeIndent sniff because it wanted the curly closer indented to the case body, but braces generically align with their scope condition (the CASE/DEFAULT in this case, but normally things like FOR/IF etc).

But the PSR2 sniff doesn't allow curly braces to be used for opening and closing CASE/DEFAULT statements, so it didn't need to actually do the check if it didn't find the T_COLON opener.

The second issue was that when the tokenizer sees the curly braces, it reassigns them as the opener and closer of the DEFAULT statement, but it didn't properly clean up the old opener and closer. If you go through the token stack, the old opener and closer still had scope_condition/opener/closer set, and the old closer didn't have the DEFAULT in it's conditions array. So that could confuse some sniffs, like the NonExecutableCode one.

Both problems are now fixed.

@dregad
Copy link
Author

dregad commented Jan 12, 2016

Hello Greg,

Many thanks for the fast reply and for the fix. I confirm this resolves the issue.
Keep up the good work !

Cheers
Damien

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