Trailing commas

Problem
-------
Trailing commas are not supported.

Solution
--------
This adds support for that.
pull/481/head
Eugene Yokota 2023-01-19 01:38:12 +07:00
parent f6bbf35de4
commit 944196126a
6 changed files with 82 additions and 22 deletions

@ -174,7 +174,9 @@ Imports
import PartialFunction.condOpt
import a.b, c.e
import reflect.io.{Directory, File, Path}
import a.{
b,
}
---
(compilation_unit
@ -186,7 +188,9 @@ import reflect.io.{Directory, File, Path}
(identifier) (identifier))
(import_declaration
(identifier) (identifier)
(namespace_selectors (identifier) (identifier) (identifier))))
(namespace_selectors (identifier) (identifier) (identifier)))
(import_declaration (identifier)
(namespace_selectors (identifier))))
================================
Imports: Wildcard
@ -307,7 +311,10 @@ object O3 extends A {
Class definitions
=======================================
class C[T, U] {
class C[
T,
U,
] {
}
---
@ -397,7 +404,10 @@ end A
Class definitions with parameters
=======================================
class Point(val x: Int, val y: Int)(implicit coord: Coord)
class Point(
val x: Int,
val y: Int,
)(implicit coord: Coord)
// TODO: The last argument should become class_parameters
class A @Inject()(x: Int, y: Int)
@ -734,7 +744,10 @@ Function definitions
=======================================
class A {
def b(c: D, e: F) = 1
def b(
c: D,
e: F,
) = 1
def g[H](i) {
j
}

@ -5,7 +5,10 @@ Call expressions
class C {
def main() {
a()
a(123)
a(
123,
234,
)
::(123)
a(b, c)
a.map(x => x + 1)
@ -27,7 +30,7 @@ class C {
(parameters)
(block
(call_expression (identifier) (arguments))
(call_expression (identifier) (arguments (integer_literal)))
(call_expression (identifier) (arguments (integer_literal) (integer_literal)))
(call_expression (operator_identifier) (arguments (integer_literal)))
(call_expression (identifier) (arguments (identifier) (identifier)))
(call_expression (field_expression (identifier) (identifier)) (arguments
@ -122,7 +125,10 @@ Generic functions
class C {
def main() {
a[T]()
a[
A1,
A2,
]()
List[Traversable[ClassPath]]()
}
}
@ -140,7 +146,7 @@ class C {
(call_expression
(generic_function
(identifier)
(type_arguments (type_identifier)))
(type_arguments (type_identifier) (type_identifier)))
(arguments))
(call_expression
(generic_function

@ -159,3 +159,19 @@ lazy val nullObject: String = null
---
(compilation_unit (val_definition (modifiers) (identifier) (type_identifier) (null_literal)))
==========================
Tuple literals
==========================
val x = (
1,
2,
3,
)
---
(compilation_unit
(val_definition (identifier)
(tuple_expression (integer_literal) (integer_literal) (integer_literal))))

@ -27,7 +27,10 @@ Generic types
===================================
object Main {
type A = B[C, D]
type A = B[
C,
D,
]
type E = F.G[H]
}
@ -52,12 +55,21 @@ Tuple types
object Main {
type A = (B, C)
type A = (
B,
C,
)
}
---
(compilation_unit
(object_definition (identifier) (template_body
(type_definition
(type_identifier)
(tuple_type
(type_identifier)
(type_identifier)))
(type_definition
(type_identifier)
(tuple_type

@ -210,7 +210,7 @@ module.exports = grammar({
namespace_selectors: $ => seq(
'{',
commaSep1(choice(
trailingCommaSep1(choice(
$._namespace_given_by_type,
$.namespace_wildcard,
$.identifier,
@ -279,7 +279,7 @@ module.exports = grammar({
// make that distinction.
type_parameters: $ => seq(
'[',
commaSep1($._variant_type_parameter),
trailingCommaSep1($._variant_type_parameter),
']'
),
@ -599,14 +599,14 @@ module.exports = grammar({
class_parameters: $ => prec(1, seq(
'(',
optional(choice('implicit', 'using')),
commaSep($.class_parameter),
trailingCommaSep($.class_parameter),
')'
)),
parameters: $ => seq(
'(',
optional(choice('implicit', 'using')),
commaSep($.parameter),
trailingCommaSep($.parameter),
')'
),
@ -704,7 +704,7 @@ module.exports = grammar({
tuple_type: $ => seq(
'(',
commaSep1($._type),
trailingCommaSep1($._type),
')',
),
@ -747,7 +747,7 @@ module.exports = grammar({
parameter_types: $ => prec(-1, choice(
$._annotated_type,
// Prioritize a parenthesized param list over a single tuple_type.
prec.dynamic(1, seq('(', commaSep($._param_type), ')' )),
prec.dynamic(1, seq('(', trailingCommaSep($._param_type), ')' )),
$.compound_type,
$.infix_type,
)),
@ -790,7 +790,7 @@ module.exports = grammar({
case_class_pattern: $ => seq(
field('type', choice($._type_identifier, $.stable_type_identifier)),
'(',
field('pattern', commaSep($._pattern)),
field('pattern', trailingCommaSep($._pattern)),
')'
),
@ -939,7 +939,7 @@ module.exports = grammar({
bindings: $ => seq(
'(',
commaSep($.binding),
trailingCommaSep($.binding),
')',
),
@ -1098,6 +1098,7 @@ module.exports = grammar({
'(',
$.expression,
repeat1(seq(',', $.expression)),
optional(','),
')'
),
@ -1109,13 +1110,13 @@ module.exports = grammar({
type_arguments: $ => seq(
'[',
commaSep1($._type),
trailingCommaSep1($._type),
']'
),
arguments: $ => seq(
'(',
commaSep($.expression),
trailingCommaSep($.expression),
')'
),
@ -1428,6 +1429,18 @@ function commaSep1(rule) {
return sep1(',', rule)
}
function trailingCommaSep(rule) {
return optional(trailingCommaSep1(rule))
}
function trailingCommaSep1(rule) {
return trailingSep1(',', rule)
}
function trailingSep1(delimiter, rule) {
return seq(sep1(delimiter, rule), optional(delimiter))
}
function sep1(delimiter, rule) {
return seq(rule, repeat(seq(delimiter, rule)))
}

@ -3,8 +3,8 @@
# This is an integration test to generally check the quality of parsing.
SCALA_SCALA_LIBRARY_EXPECTED=100
SCALA_SCALA_COMPILER_EXPECTED=67
DOTTY_COMPILER_EXPECTED=66
SCALA_SCALA_COMPILER_EXPECTED=66
DOTTY_COMPILER_EXPECTED=65
if [ ! -d "$SCALA_SCALA_DIR" ]; then
echo "\$SCALA_SCALA_DIR must be set"