tolerant-php-parser icon indicating copy to clipboard operation
tolerant-php-parser copied to clipboard

Better disambiguation between subscript-expression and compound-statement

Open mousetraps opened this issue 8 years ago • 1 comments
trafficstars

This error tolerance case needs some special handling.

class A {
    function b() {
        if ($expression {
            $a = 3;
            $b = "hello";
        }
        echo "hi";
    }
    
    public function c() {
    }
}

In this case, the if statement is missing a close paren. However, rather than getting parsed as an if-statement missing a close paren, it gets parsed as a subscript-expression (which is defined as follows, according to the PHP language spec.

subscript-expression:
  dereferencable-expression   [   expressionopt   ]
  dereferencable-expression   {   expression   }   <b>[Deprecated form]</b>

This results in the first close brace getting treated as a close brace for the method, rather than the if statement. Then the next close brace gets eaten by the Class node (which terminates the class), so c() ends up being a function, rather than a method.

mousetraps avatar Jan 17 '17 23:01 mousetraps

I've been giving this some thought recently, and because the {}-syntax is valid code, the ideal way to determine the problem could involve an non-trivial amount of lookahead. Theoretically, a quick, potentially invalid diagnostic could be created by checking if the first '{' has a trailing newline though. As none of these solutions are very good in my opinion, I would actually just leave it alone. I don't see many people typing out if ($expression { in the first place, especially since most IDEs would automatically put in the closing parenthesis after the opening one.

mattacosta avatar Mar 02 '17 23:03 mattacosta