diff --git a/unified/extractor/src/languages/swift/swift.rs b/unified/extractor/src/languages/swift/swift.rs index 21a8c5009bb3..9f40c0a97d57 100644 --- a/unified/extractor/src/languages/swift/swift.rs +++ b/unified/extractor/src/languages/swift/swift.rs @@ -279,14 +279,22 @@ fn translation_rules() -> Vec> { rule!((sequenceExpr elements: _* @els) => (unresolved_operator_sequence element: {els})), // Prefix unary operators (`!a`, `-x`). rule!((prefixOperatorExpr operator: @op expression: @operand) => (unary_expr operator: (prefix_operator #{op}) operand: {operand})), - // A `tupleExpr` is a tuple literal (`(a, b)`) or a parenthesised - // expression (`(x)`). For now it is kept as an opaque `tuple_expr` leaf - // (its source text); its elements are not descended into. - // - // TODO: a parenthesised single-element `tupleExpr` is really a grouping - // expression and should be elided (unwrapped to its inner expression) - // rather than modelled as a tuple. - rule!((tupleExpr) => (tuple_expr)), + // A single-element `tupleExpr` is a parenthesised expression, so elide + // the grouping rather than modelling it as a tuple. + rule!( + (tupleExpr + elements: (labeledExpr + label: _? @label + expression: @e + trailingComma: _? @trailing_comma) + elements: _* @rest) + where label.is_none() && trailing_comma.is_none() && rest.is_empty() + => + expr { e } + ), + // Other `tupleExpr` forms are tuple literals. Their labelled + // expressions translate to `argument`s. + rule!((tupleExpr elements: _* @els) => (tuple_expr element: {els})), // A code block contains its statements directly. rule!((codeBlock statements: _* @stmts) => (block stmt: {stmts})), // ---- Properties with accessors ---- diff --git a/unified/extractor/tests/corpus/swift/collections/tuple-literal.output b/unified/extractor/tests/corpus/swift/collections/tuple-literal.output index 5d7742f744bc..4a8a54078d9c 100644 --- a/unified/extractor/tests/corpus/swift/collections/tuple-literal.output +++ b/unified/extractor/tests/corpus/swift/collections/tuple-literal.output @@ -52,4 +52,12 @@ top_level variable_declaration modifier: modifier "let" pattern: identifier "t" - value: tuple_expr "(1, \"two\", 3.0)" + value: + tuple_expr + element: + argument + value: int_literal "1" + argument + value: string_literal "\"two\"" + argument + value: float_literal "3.0" diff --git a/unified/extractor/tests/corpus/swift/control-flow/switch-expression-pattern.output b/unified/extractor/tests/corpus/swift/control-flow/switch-expression-pattern.output index 0a4fe7302b05..533f717b827e 100644 --- a/unified/extractor/tests/corpus/swift/control-flow/switch-expression-pattern.output +++ b/unified/extractor/tests/corpus/swift/control-flow/switch-expression-pattern.output @@ -333,7 +333,12 @@ top_level member_access_expr base: inferred_type_expr "." member_name_node: identifier "inferred" - tuple_expr "(value, offset)" + tuple_expr + element: + argument + value: identifier "value" + argument + value: identifier "offset" array_literal element: identifier "value" map_literal "[key: value]" diff --git a/unified/extractor/tests/corpus/swift/operators/parenthesised-expression.output b/unified/extractor/tests/corpus/swift/operators/parenthesised-expression.output index 1c8de726f41a..33bb1599ff1a 100644 --- a/unified/extractor/tests/corpus/swift/operators/parenthesised-expression.output +++ b/unified/extractor/tests/corpus/swift/operators/parenthesised-expression.output @@ -39,6 +39,10 @@ top_level block stmt: binary_expr - left: tuple_expr "(a + b)" + left: + binary_expr + left: identifier "a" + operator: infix_operator "+" + right: identifier "b" operator: infix_operator "*" right: identifier "c"