From f6f670834b158aec01cf9ee869160e1aad58acc6 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 14 Dec 2024 02:16:59 -0500 Subject: [PATCH] SIP-58 Named Tuples support **Problem** Named tuples are now available as an experimental feature. **Solution** This implements a support for them. --- grammar.js | 38 +++++++++++++++++++++++++++++++++++++- test/corpus/patterns.txt | 25 +++++++++++++++++++++++++ test/corpus/types.txt | 23 +++++++++++++++++++++++ 3 files changed, 85 insertions(+), 1 deletion(-) diff --git a/grammar.js b/grammar.js index 42b1b82..a50fa50 100644 --- a/grammar.js +++ b/grammar.js @@ -91,6 +91,11 @@ module.exports = grammar({ [$.class_parameters], // 'for' operator_identifier ':' _annotated_type • ':' … [$._type, $.compound_type], + // 'given' '(' operator_identifier ':' _type • ',' … + [$.name_and_type, $.parameter], + [$._simple_expression, $.binding, $.tuple_pattern], + [$._simple_expression, $.tuple_pattern], + [$._simple_expression, $._type_identifier], // 'if' parenthesized_expression • '{' … [$._if_condition, $._simple_expression], // _postfix_expression_choice ':' '(' wildcard • ':' … @@ -785,6 +790,19 @@ module.exports = grammar({ ), ), + /* + * NameAndType ::= id ':' Type + */ + name_and_type: $ => + prec.left( + PREC.control, + seq( + field("name", $._identifier), + ":", + field("type", $._param_type), + ), + ), + _block: $ => prec.left( seq( @@ -837,6 +855,7 @@ module.exports = grammar({ $.generic_type, $.projected_type, $.tuple_type, + $.named_tuple_type, $.singleton_type, $.stable_type_identifier, $._type_identifier, @@ -897,6 +916,12 @@ module.exports = grammar({ tuple_type: $ => seq("(", trailingCommaSep1($._type), ")"), + named_tuple_type: $ => seq( + "(", + trailingCommaSep1($.name_and_type), + ")", + ), + singleton_type: $ => prec.left( PREC.stable_type_id, @@ -991,6 +1016,7 @@ module.exports = grammar({ $.interpolated_string_expression, $.capture_pattern, $.tuple_pattern, + $.named_tuple_pattern, $.case_class_pattern, $.infix_pattern, $.alternative_pattern, @@ -1034,16 +1060,26 @@ module.exports = grammar({ typed_pattern: $ => prec.right( + -1, seq(field("pattern", $._pattern), ":", field("type", $._type)), ), given_pattern: $ => seq("given", field("type", $._type)), // TODO: Flatten this. - alternative_pattern: $ => prec.left(-1, seq($._pattern, "|", $._pattern)), + alternative_pattern: $ => prec.left(-2, seq($._pattern, "|", $._pattern)), tuple_pattern: $ => seq("(", $._pattern, repeat(seq(",", $._pattern)), ")"), + named_pattern: $ => prec.left(-1, seq($._identifier, "=", $._pattern)), + + named_tuple_pattern: $ => seq( + "(", + $.named_pattern, + repeat(seq(",", $.named_pattern)), + ")", + ), + // --------------------------------------------------------------- // Expressions diff --git a/test/corpus/patterns.txt b/test/corpus/patterns.txt index 503b62d..d7117ed 100644 --- a/test/corpus/patterns.txt +++ b/test/corpus/patterns.txt @@ -111,6 +111,31 @@ val x = y match { (identifier)) (identifier)))))) +================================================================================ +Name tuple patterns (Scala 3 syntax) +================================================================================ + +val x = y match + case (a = A, b = B) => ??? + +-------------------------------------------------------------------------------- + +(compilation_unit + (val_definition + (identifier) + (match_expression + (identifier) + (indented_cases + (case_clause + (named_tuple_pattern + (named_pattern + (identifier) + (identifier)) + (named_pattern + (identifier) + (identifier))) + (operator_identifier)))))) + ================================================================================ Case class patterns ================================================================================ diff --git a/test/corpus/types.txt b/test/corpus/types.txt index a239d0b..ff18e85 100644 --- a/test/corpus/types.txt +++ b/test/corpus/types.txt @@ -97,6 +97,29 @@ object Main { (type_identifier) (type_identifier)))))) +================================================================================ +Named tuple types (Scala 3 syntax) +================================================================================ + +object O: + type A = (name: String, age: Int) + +-------------------------------------------------------------------------------- + +(compilation_unit + (object_definition + (identifier) + (template_body + (type_definition + (type_identifier) + (named_tuple_type + (name_and_type + (identifier) + (type_identifier)) + (name_and_type + (identifier) + (type_identifier))))))) + ================================================================================ Function types ================================================================================