diff --git a/corpus/expressions.txt b/corpus/expressions.txt index 4a8dce41a..a4937cd86 100644 --- a/corpus/expressions.txt +++ b/corpus/expressions.txt @@ -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)))))))) diff --git a/grammar.js b/grammar.js index 260074d00..5c10b2f55 100644 --- a/grammar.js +++ b/grammar.js @@ -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 >>> diff --git a/test/highlight/basics.scala b/test/highlight/basics.scala index 9c9f98884..e2449e41d 100644 --- a/test/highlight/basics.scala +++ b/test/highlight/basics.scala @@ -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)