diff --git a/grammar.js b/grammar.js index 6a535e5..d109d3d 100644 --- a/grammar.js +++ b/grammar.js @@ -3,6 +3,7 @@ const PREC = { using_directive: 2, control: 1, stable_type_id: 2, + type: 2, while: 2, assign: 3, case: 3, @@ -98,8 +99,12 @@ module.exports = grammar({ [$._simple_expression, $._type_identifier], // 'if' parenthesized_expression • '{' … [$._if_condition, $._simple_expression], - // _postfix_expression_choice ':' '(' wildcard • ':' … - [$.binding, $._simple_type], + [$.block, $._braced_template_body1], + [$._simple_expression, $.self_type, $._type_identifier], + [$._simple_expression, $._type_identifier], + [$.lambda_expression, $.self_type, $._type_identifier], + [$.lambda_expression, $._type_identifier], + [$.binding, $._simple_expression, $._type_identifier], ], word: $ => $._alpha_identifier, @@ -369,7 +374,7 @@ module.exports = grammar({ field("bound", optional($.lower_bound)), field("bound", optional($.upper_bound)), field("bound", optional(repeat($.view_bound))), - field("bound", optional(repeat($.context_bound))), + field("bound", optional($._context_bounds)), ), upper_bound: $ => seq("<:", field("type", $._type)), @@ -378,7 +383,26 @@ module.exports = grammar({ view_bound: $ => seq("<%", field("type", $._type)), - context_bound: $ => seq(":", field("type", $._type)), + _context_bounds: $ => choice( + repeat1(seq( + ":", + $.context_bound + )), + seq( + ":", + "{", + trailingCommaSep1($.context_bound), + "}", + ) + ), + + context_bound: $ => seq( + field("type", $._type), + optional(seq( + "as", + field("name", $._identifier), + )), + ), /* * TemplateBody ::= :<<< [SelfType] TemplateStat {semi TemplateStat} >>> @@ -525,6 +549,7 @@ module.exports = grammar({ field("type_parameters", optional($.type_parameters)), field("bound", optional($.lower_bound)), field("bound", optional($.upper_bound)), + field("bound", optional($._context_bounds)), ), ), @@ -602,6 +627,7 @@ module.exports = grammar({ optional($.modifiers), "given", optional($._given_constructor), + repeat($._given_sig), choice( field("return_type", $._structural_instance), seq( @@ -612,6 +638,14 @@ module.exports = grammar({ ), ), + _given_sig: $ => + seq( + $._given_conditional, + "=>" + ), + + _given_conditional: $ => alias($.parameters, $.given_conditional), + _given_constructor: $ => prec.right( seq( @@ -634,7 +668,10 @@ module.exports = grammar({ PREC.compound, seq( $._constructor_application, - "with", + choice( + ":", + "with" + ), field("body", $.with_template_body), ), ), @@ -851,15 +888,18 @@ module.exports = grammar({ annotated_type: $ => prec.right(seq($._simple_type, repeat1($.annotation))), _simple_type: $ => - choice( - $.generic_type, - $.projected_type, - $.tuple_type, - $.named_tuple_type, - $.singleton_type, - $.stable_type_identifier, - $._type_identifier, - $.wildcard, + prec.left( + PREC.type, + choice( + $.generic_type, + $.projected_type, + $.tuple_type, + $.named_tuple_type, + $.singleton_type, + $.stable_type_identifier, + $._type_identifier, + $.wildcard, + ) ), compound_type: $ => @@ -1562,7 +1602,8 @@ module.exports = grammar({ $.string, ), - literal_type: $ => $._non_null_literal, + literal_type: $ => + prec.left(PREC.type, $._non_null_literal), literal: $ => choice($._non_null_literal, $.null_literal), diff --git a/test/corpus/definitions.txt b/test/corpus/definitions.txt index 244096d..98477d8 100644 --- a/test/corpus/definitions.txt +++ b/test/corpus/definitions.txt @@ -1027,6 +1027,25 @@ class A { (type_parameters (identifier)))))) +================================================================================ +Type definitions (Scala 3 syntax) +================================================================================ + +class A: + type Element: Order + +-------------------------------------------------------------------------------- + +(compilation_unit + (class_definition + (identifier) + (template_body + (type_definition + (type_identifier) + (context_bound + (type_identifier)))))) + + ================================================================================ Function declarations ================================================================================ @@ -1290,6 +1309,9 @@ object A: given intFoo: CanFoo[Int] with def foo(x: Int): Int = 0 + given intFoo: CanFoo[Int]: + def foo(x: Int): Int = 0 + given CanFoo[Int] with def foo(x: Int): Int = 0 @@ -1317,6 +1339,8 @@ object A: trait B: given c: Context[T] + given (config: Config) => Factory = ConcreteFactory() + -------------------------------------------------------------------------------- (compilation_unit @@ -1342,6 +1366,21 @@ object A: (type_identifier))) (type_identifier) (integer_literal)))) + (given_definition + (identifier) + (generic_type + (type_identifier) + (type_arguments + (type_identifier))) + (with_template_body + (function_definition + (identifier) + (parameters + (parameter + (identifier) + (type_identifier))) + (type_identifier) + (integer_literal)))) (given_definition (generic_type (type_identifier) @@ -1464,7 +1503,16 @@ object A: (generic_type (type_identifier) (type_arguments - (type_identifier))))))))) + (type_identifier)))))) + (given_definition + (given_conditional + (parameter + (identifier) + (type_identifier))) + (type_identifier) + (call_expression + (identifier) + (arguments)))))) ================================================================================ Top-level Definitions (Scala 3 syntax) diff --git a/test/corpus/types.txt b/test/corpus/types.txt index ff18e85..922a812 100644 --- a/test/corpus/types.txt +++ b/test/corpus/types.txt @@ -426,6 +426,51 @@ class A[B : C : D] (context_bound (type_identifier))))) +================================================================================ +Context bound (Scala 3 syntax) +================================================================================ + +def reduce[A : Monoid as m](xs: List[A]): A = () + +def showMax[X : {Ordering, Show}](x: X, y: X): String = () + +-------------------------------------------------------------------------------- + +(compilation_unit + (function_definition + (identifier) + (type_parameters + (identifier) + (context_bound + (type_identifier) + (identifier))) + (parameters + (parameter + (identifier) + (generic_type + (type_identifier) + (type_arguments + (type_identifier))))) + (type_identifier) + (unit)) + (function_definition + (identifier) + (type_parameters + (identifier) + (context_bound + (type_identifier)) + (context_bound + (type_identifier))) + (parameters + (parameter + (identifier) + (type_identifier)) + (parameter + (identifier) + (type_identifier))) + (type_identifier) + (unit))) + ================================================================================ Projections ================================================================================