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

Case statements not tokenized correctly when switch is contained within ternary #2688

Closed
xaviered opened this issue Nov 12, 2019 · 2 comments
Milestone

Comments

@xaviered
Copy link

Hello, I think my team found an issue with the SwitchDeclaration sniffer. This happens when we try to define a SWITCH statement inside an anonymous function inside a ternary operator.
Here is a script with examples:

<?php
/**
 * Testing document
 */

$diff_lines = ['@', '4', '+', '-', '23', 'adsf'];
$diff2 = $diff_lines ?
    function ($line) {
        switch ($line[0]) {
            case 'what':
                $type = 'what';
                break;
            case '@':
                $type = 'section';
                break;
            case '+':
                $type = 'add';
                break;
            case '-':
                $type = 'subtract';
                break;
            default:
                $type = 'ignore';
        }
        return $type;
    } :
    null;

/**
 * Test function
 *
 * @return array
 */
function test(): void
{
    global $diff_lines, $diff2;

    $diff = $diff_lines ?
        array_map(
            function ($line) {
                switch ($line[0]) {
                    case '@' :
                        $type = 'section';
            break;
                    case '+':
                        $type = 'add';
                        break;
                    case '-':
                        $type = 'subtract';
                        break;
                    default:
                        $type = 'ignore';
                }
                return $type;
            },
            $diff_lines
        ) :
        ['section' => 'No changes found.'];


    $result = [
        'response' => [
            'blog_id' => 1,
            'timestamp' => 2323,
            'diff' => $diff,
            'diff2' => $diff2,
        ],
    ];

    return $result;
}

print_r(test());

Running this code against latest version of phpcs returns errors:

$ php --version
PHP 7.2.24 (cli) (built: Oct 22 2019 11:15:01) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.2.24, Copyright (c) 1999-2018, by Zend Technologies
    with Xdebug v2.7.2, Copyright (c) 2002-2019, by Derick Rethans

$  vendor/bin/phpcs --standard=PSR2 test_file.php

FILE: test_file.php
-------------------------------------------------------------------------------------------------------
FOUND 2 ERRORS AND 1 WARNING AFFECTING 3 LINES
-------------------------------------------------------------------------------------------------------
  1 | WARNING | A file should declare new symbols (classes, functions, constants, etc.) and cause no
    |         | other side effects, or it should execute logic with side effects, but should not do
    |         | both. The first symbol is defined on line 34 and the first side effect is on line 6.
 10 | ERROR   | CASE statements must be defined using a colon
 42 | ERROR   | CASE statements must be defined using a colon
-------------------------------------------------------------------------------------------------------

Time: 103ms; Memory: 6MB

Please advice if you need further information. Thank you.

@gsherwood
Copy link
Member

The problem here lies in the tokenizer. It is tokenzing the first T_COLON in the switch statement as T_INLINE_ELSE because it thinks it is in an inline condition.

A simple case for testing:

$foo = $foo ?
    function () {
        switch ($a) {
            case 'a':
                break;
        }
    } :
    null;

@gsherwood gsherwood added this to the 3.5.4 milestone Dec 9, 2019
@gsherwood gsherwood changed the title PSR2.ControlStructures.SwitchDeclaration.WrongOpenercase Error on specific format Case statements not tokenized correctly when switch is contained within ternary Dec 16, 2019
gsherwood added a commit that referenced this issue Dec 16, 2019
@gsherwood
Copy link
Member

I've added a fix for this in master, which will be released in 3.5.4. Thanks for reporting it.

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

2 participants