Skip to content

Commit 545b40f

Browse files
authored
Allow newlines before '(' in call expressions in when conditions (#53)
In Kotlin, newlines are not allowed before `(` in call expressions. However, there is an exception in when conditions: newlines are allowed there! This is not specified in the Kotlin specifications but the Kotlin compiler behaves like this. To fix this, we have to copy the expression nonterminal in `when_condition` and change the `call_expression` node with another one that allows newlines. Also, changes should be made in the lexer to allow this.
1 parent 21d7b71 commit 545b40f

File tree

6 files changed

+1613699
-1496953
lines changed

6 files changed

+1613699
-1496953
lines changed

grammar.js

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,11 +236,13 @@ module.exports = grammar({
236236
"]",
237237
"${",
238238
$._not_is,
239+
$._external_nl_when_condition,
239240
],
240241

241242
supertypes: $ => [
242243
$.expression,
243244
$.jump_expression,
245+
$.when_condition_expression
244246
],
245247

246248
word: $ => $._alpha_identifier,
@@ -836,6 +838,15 @@ module.exports = grammar({
836838
$._loop_statement
837839
),
838840

841+
when_condition_expression: $ => choice(
842+
$._unary_expression,
843+
$._binary_expression,
844+
$._when_condition_primary_expression,
845+
$.jump_expression,
846+
$.assignment,
847+
$._loop_statement
848+
),
849+
839850
// Unary expressions
840851

841852
_unary_expression: $ => choice(
@@ -875,6 +886,13 @@ module.exports = grammar({
875886
$._call_arguments
876887
)),
877888

889+
when_condition_call_expression: $ => prec("call", seq(
890+
field("expression", $.expression),
891+
optional($.type_arguments),
892+
repeat($._external_nl_when_condition),
893+
$._call_arguments
894+
)),
895+
878896
// It's not possible to resolve the ambiguity between explicit delegation and calls with last lambda argument.
879897
// For example:
880898
// class Derived(b: Base) : Base by b {
@@ -1110,6 +1128,11 @@ module.exports = grammar({
11101128
$._non_call_primary_expression
11111129
),
11121130

1131+
_when_condition_primary_expression: $ => choice(
1132+
$.when_condition_call_expression,
1133+
$._non_call_primary_expression
1134+
),
1135+
11131136
// we need to give parenthesized expression a lower dynamic precedence to resolve ambiguities like
11141137
// @Annotation() in favor of a single annotation rather than an annotation of a parenthesized expression.
11151138
parenthesized_expression: $ => prec.dynamic(-1, seq("(", repeat($._NL), $.expression, repeat($._NL), ")")),
@@ -1336,7 +1359,7 @@ module.exports = grammar({
13361359
),
13371360

13381361
when_condition: $ => choice(
1339-
$.expression,
1362+
$.when_condition_expression,
13401363
$.range_test,
13411364
$.type_test
13421365
),

src/grammar.json

Lines changed: 89 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4192,6 +4192,35 @@
41924192
}
41934193
]
41944194
},
4195+
"when_condition_expression": {
4196+
"type": "CHOICE",
4197+
"members": [
4198+
{
4199+
"type": "SYMBOL",
4200+
"name": "_unary_expression"
4201+
},
4202+
{
4203+
"type": "SYMBOL",
4204+
"name": "_binary_expression"
4205+
},
4206+
{
4207+
"type": "SYMBOL",
4208+
"name": "_when_condition_primary_expression"
4209+
},
4210+
{
4211+
"type": "SYMBOL",
4212+
"name": "jump_expression"
4213+
},
4214+
{
4215+
"type": "SYMBOL",
4216+
"name": "assignment"
4217+
},
4218+
{
4219+
"type": "SYMBOL",
4220+
"name": "_loop_statement"
4221+
}
4222+
]
4223+
},
41954224
"_unary_expression": {
41964225
"type": "CHOICE",
41974226
"members": [
@@ -4364,6 +4393,46 @@
43644393
]
43654394
}
43664395
},
4396+
"when_condition_call_expression": {
4397+
"type": "PREC",
4398+
"value": "call",
4399+
"content": {
4400+
"type": "SEQ",
4401+
"members": [
4402+
{
4403+
"type": "FIELD",
4404+
"name": "expression",
4405+
"content": {
4406+
"type": "SYMBOL",
4407+
"name": "expression"
4408+
}
4409+
},
4410+
{
4411+
"type": "CHOICE",
4412+
"members": [
4413+
{
4414+
"type": "SYMBOL",
4415+
"name": "type_arguments"
4416+
},
4417+
{
4418+
"type": "BLANK"
4419+
}
4420+
]
4421+
},
4422+
{
4423+
"type": "REPEAT",
4424+
"content": {
4425+
"type": "SYMBOL",
4426+
"name": "_external_nl_when_condition"
4427+
}
4428+
},
4429+
{
4430+
"type": "SYMBOL",
4431+
"name": "_call_arguments"
4432+
}
4433+
]
4434+
}
4435+
},
43674436
"simple_call_expression": {
43684437
"type": "PREC",
43694438
"value": "call",
@@ -5675,6 +5744,19 @@
56755744
}
56765745
]
56775746
},
5747+
"_when_condition_primary_expression": {
5748+
"type": "CHOICE",
5749+
"members": [
5750+
{
5751+
"type": "SYMBOL",
5752+
"name": "when_condition_call_expression"
5753+
},
5754+
{
5755+
"type": "SYMBOL",
5756+
"name": "_non_call_primary_expression"
5757+
}
5758+
]
5759+
},
56785760
"parenthesized_expression": {
56795761
"type": "PREC_DYNAMIC",
56805762
"value": -1,
@@ -7128,7 +7210,7 @@
71287210
"members": [
71297211
{
71307212
"type": "SYMBOL",
7131-
"name": "expression"
7213+
"name": "when_condition_expression"
71327214
},
71337215
{
71347216
"type": "SYMBOL",
@@ -9669,12 +9751,17 @@
96699751
{
96709752
"type": "SYMBOL",
96719753
"name": "_not_is"
9754+
},
9755+
{
9756+
"type": "SYMBOL",
9757+
"name": "_external_nl_when_condition"
96729758
}
96739759
],
96749760
"inline": [],
96759761
"supertypes": [
96769762
"expression",
9677-
"jump_expression"
9763+
"jump_expression",
9764+
"when_condition_expression"
96789765
],
96799766
"reserved": {}
96809767
}

0 commit comments

Comments
 (0)