Fix parenthesized expressions in braceless `if` conditions

Fixes #263 and #342
`_if_condition` extracted from `if_expression` and given a magic dynamic
precedence of 4
pull/659/head
susliko 2023-09-17 01:24:51 +07:00
parent 70afdd5632
commit f8d3848919
3 changed files with 55 additions and 24 deletions

@ -404,6 +404,11 @@ class C:
else
()
if (a) || b(c) then return true
if (a) && b.c then
()
--------------------------------------------------------------------------------
(compilation_unit
@ -445,6 +450,27 @@ class C:
(indented_block
(unit)
(comment))
(indented_block
(unit)))
(if_expression
(infix_expression
(parenthesized_expression
(identifier))
(operator_identifier)
(call_expression
(identifier)
(arguments
(identifier))))
(return_expression
(boolean_literal)))
(if_expression
(infix_expression
(parenthesized_expression
(identifier))
(operator_identifier)
(field_expression
(identifier)
(identifier)))
(indented_block
(unit))))))))

@ -92,6 +92,8 @@ module.exports = grammar({
// 'for' operator_identifier ':' _annotated_type • ':' …
[$._type, $.compound_type],
[$.lambda_expression, $.modifiers],
// 'if' parenthesized_expression • '{' …
[$._if_condition, $._simple_expression],
],
word: $ => $._alpha_identifier,
@ -1104,22 +1106,25 @@ module.exports = grammar({
),
if_expression: $ =>
prec.right(
PREC.control,
seq(
optional($.inline_modifier),
"if",
field(
"condition",
choice(
$.parenthesized_expression,
seq($._indentable_expression, "then"),
),
),
field("consequence", $._indentable_expression),
optional(seq("else", field("alternative", $._indentable_expression))),
),
),
prec.right(PREC.control, seq(
optional($.inline_modifier),
"if",
field(
"condition",
$._if_condition,
),
field("consequence", $._indentable_expression),
optional(seq("else", field("alternative", $._indentable_expression))),
)),
// NOTE(susliko): _if_condition and its magic dynamic precedence were introduced as a fix to
// https://github.com/tree-sitter/tree-sitter-scala/issues/263 and
// https://github.com/tree-sitter/tree-sitter-scala/issues/342
// Neither do I understand why this works, nor have I found a better solution
_if_condition: $ => prec.dynamic(4, choice(
$.parenthesized_expression,
seq($._indentable_expression, "then"),
)),
/*
* MatchClause ::= 'match' <<< CaseClauses >>>

@ -26,19 +26,19 @@ object Hello {
trait Test {
// ^ keyword
// ^ type
def meth(i: Int)(implicit x: Boolean) = ???
def meth(i: Int)(implicit x: Boolean) = ???
// ^keyword.function
// ^keyword
// ^type
// ^method
// ^parameter
// ^parameter
val anonFun: Int => Int = (a: Int) => a
// ^variable
// ^type
// ^operator
// ^type
// ^parameter
val anonFun: Int => Int = (a: Int) => a
// ^variable
// ^type
// ^operator
// ^type
// ^parameter
}
protected abstract class Bla(test: String)