diff --git a/corpus/definitions.txt b/corpus/definitions.txt index 7a4e3ebf2..c640e1597 100644 --- a/corpus/definitions.txt +++ b/corpus/definitions.txt @@ -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 } diff --git a/corpus/expressions.txt b/corpus/expressions.txt index fd20f7593..51d14cf4b 100644 --- a/corpus/expressions.txt +++ b/corpus/expressions.txt @@ -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 diff --git a/corpus/literals.txt b/corpus/literals.txt index 1127c10db..28f3a3b78 100644 --- a/corpus/literals.txt +++ b/corpus/literals.txt @@ -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)))) diff --git a/corpus/types.txt b/corpus/types.txt index 5c911acf5..c925b71e2 100644 --- a/corpus/types.txt +++ b/corpus/types.txt @@ -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 diff --git a/grammar.js b/grammar.js index ae1bbcb07..c8fdcabdd 100644 --- a/grammar.js +++ b/grammar.js @@ -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))) } diff --git a/script/smoke_test.sh b/script/smoke_test.sh index ca08909af..b0f20550b 100755 --- a/script/smoke_test.sh +++ b/script/smoke_test.sh @@ -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"