tree-sitter / tree-sitter-javascript

Javascript grammar for tree-sitter
MIT License
323 stars 109 forks source link

Empty bodies mustn't be an empty object #104

Closed calixteman closed 4 years ago

calixteman commented 4 years ago

In expression for (...) { } the empty body is treated like an object because followed by an automatic_semicolon. So this expression is equivalent to to for (...) { }; and the empty object is finally an expression statement... which is of course wrong. Anyway an object cannot be an expression_statement when it's the body, ideally we should forbid that with the grammar but it seems to be quite a pain.... so this workaround.

maxbrunsfeld commented 4 years ago

Can you fix this just by changing precedence? See also https://github.com/tree-sitter/tree-sitter-javascript/issues/86. I don't think we need a separate token just for empty blocks.

calixteman commented 4 years ago

I tried a lot of things and each one failed:

calixteman commented 4 years ago

ah nice... I didn't think about prec.right. TIL thanks

maxbrunsfeld commented 4 years ago

each one failed

I think the problem you were seeing when using precedence is that after {}, an _automatic_semicolon token was valid because of the (expression_statement (object)) interpretation. So the lexer returned an _automatic_semicolon. Then, upon seeing that token, the parser decided to reduce by object -> '{' '}' because an automatic semicolon was not valid for a statement block.

By allowing _automatic_semicolon at the end of a statement block, we allow the parser to choose the statement_block reduction instead.