@@ -182,26 +182,53 @@ type typ_def_or_ext =
182
182
}
183
183
| TypeExt of Parsetree .type_extension
184
184
185
- type labelled_parameter =
186
- | TermParameter of {
187
- attrs : Parsetree .attributes ;
188
- label : Asttypes .arg_label ;
189
- expr : Parsetree .expression option ;
190
- pat : Parsetree .pattern ;
191
- pos : Lexing .position ;
192
- }
193
- | TypeParameter of {
194
- attrs : Parsetree .attributes ;
195
- locs : string Location .loc list ;
196
- pos : Lexing .position ;
197
- }
185
+ type fundef_type_param = {
186
+ attrs : Parsetree .attributes ;
187
+ locs : string Location .loc list ;
188
+ p_pos : Lexing .position ;
189
+ }
190
+
191
+ type fundef_term_param = {
192
+ attrs : Parsetree .attributes ;
193
+ p_label : Asttypes .arg_label ;
194
+ expr : Parsetree .expression option ;
195
+ pat : Parsetree .pattern ;
196
+ p_pos : Lexing .position ;
197
+ }
198
+
199
+ (* Single parameter of a function definition (type a b, x, ~y) *)
200
+ type fundef_parameter =
201
+ | TermParameter of fundef_term_param
202
+ | TypeParameter of fundef_type_param
198
203
199
204
type record_pattern_item =
200
205
| PatUnderscore
201
206
| PatField of (Ast_helper .lid * Parsetree .pattern * bool (* optional *) )
202
207
203
208
type context = OrdinaryExpr | TernaryTrueBranchExpr | WhenExpr
204
209
210
+ (* Extracts type and term parameters from a list of function definition parameters, combining all type parameters into one *)
211
+ let rec extract_fundef_params ~(type_acc : fundef_type_param option )
212
+ ~(term_acc : fundef_term_param list ) (params : fundef_parameter list ) :
213
+ fundef_type_param option * fundef_term_param list =
214
+ match params with
215
+ | TermParameter tp :: rest ->
216
+ extract_fundef_params ~type_acc ~term_acc: (tp :: term_acc) rest
217
+ | TypeParameter tp :: rest ->
218
+ let type_acc =
219
+ match type_acc with
220
+ | Some tpa ->
221
+ Some
222
+ {
223
+ attrs = tpa.attrs @ tp.attrs;
224
+ locs = tpa.locs @ tp.locs;
225
+ p_pos = tpa.p_pos;
226
+ }
227
+ | None -> Some tp
228
+ in
229
+ extract_fundef_params ~type_acc ~term_acc rest
230
+ | [] -> (type_acc, List. rev term_acc)
231
+
205
232
let get_closing_token = function
206
233
| Token. Lparen -> Token. Rparen
207
234
| Lbrace -> Rbrace
@@ -1510,7 +1537,7 @@ and parse_ternary_expr left_operand p =
1510
1537
| _ -> left_operand
1511
1538
1512
1539
and parse_es6_arrow_expression ?(arrow_attrs = [] ) ?(arrow_start_pos = None )
1513
- ?context ?parameters p =
1540
+ ?context ?term_parameters p =
1514
1541
let start_pos = p.Parser. start_pos in
1515
1542
Parser. leave_breadcrumb p Grammar. Es6ArrowExpr ;
1516
1543
(* Parsing function parameters and attributes:
@@ -1520,8 +1547,8 @@ and parse_es6_arrow_expression ?(arrow_attrs = []) ?(arrow_start_pos = None)
1520
1547
2. Attributes inside `(...)` are added to the arguments regardless of whether
1521
1548
labeled, optional or nolabeled *)
1522
1549
let parameters =
1523
- match parameters with
1524
- | Some params -> params
1550
+ match term_parameters with
1551
+ | Some params -> ( None , params)
1525
1552
| None -> parse_parameters p
1526
1553
in
1527
1554
let parameters =
@@ -1532,15 +1559,23 @@ and parse_es6_arrow_expression ?(arrow_attrs = []) ?(arrow_start_pos = None)
1532
1559
| None -> pos
1533
1560
in
1534
1561
match parameters with
1535
- | TermParameter p :: rest ->
1536
- TermParameter
1537
- {p with attrs = update_attrs p.attrs; pos = update_pos p.pos}
1538
- :: rest
1539
- | TypeParameter p :: rest ->
1540
- TypeParameter
1541
- {p with attrs = update_attrs p.attrs; pos = update_pos p.pos}
1542
- :: rest
1543
- | [] -> parameters
1562
+ | None , termp :: rest ->
1563
+ ( None ,
1564
+ {
1565
+ termp with
1566
+ attrs = update_attrs termp.attrs;
1567
+ p_pos = update_pos termp.p_pos;
1568
+ }
1569
+ :: rest )
1570
+ | Some (tpa : fundef_type_param ), term_params ->
1571
+ ( Some
1572
+ {
1573
+ tpa with
1574
+ attrs = update_attrs tpa.attrs;
1575
+ p_pos = update_pos tpa.p_pos;
1576
+ },
1577
+ term_params )
1578
+ | _ -> parameters
1544
1579
in
1545
1580
let return_type =
1546
1581
match p.Parser. token with
@@ -1561,32 +1596,32 @@ and parse_es6_arrow_expression ?(arrow_attrs = []) ?(arrow_start_pos = None)
1561
1596
in
1562
1597
Parser. eat_breadcrumb p;
1563
1598
let end_pos = p.prev_end_pos in
1564
- let term_parameters =
1565
- parameters
1566
- |> List. filter (function
1567
- | TermParameter _ -> true
1568
- | TypeParameter _ -> false )
1569
- in
1570
- let _paramNum, arrow_expr, _arity =
1599
+ let type_param_opt, term_parameters = parameters in
1600
+ let _paramNum, arrow_expr =
1571
1601
List. fold_right
1572
- (fun parameter (term_param_num , expr , arity ) ->
1573
- match parameter with
1574
- | TermParameter
1575
- {attrs; label = lbl; expr = default_expr; pat; pos = start_pos} ->
1576
- let loc = mk_loc start_pos end_pos in
1577
- let fun_expr =
1578
- Ast_helper.Exp. fun_ ~loc ~attrs ~arity: None lbl default_expr pat
1579
- expr
1580
- in
1581
- if term_param_num = 1 then
1582
- (term_param_num - 1 , Ast_uncurried. uncurried_fun ~arity fun_expr, 1 )
1583
- else (term_param_num - 1 , fun_expr, arity + 1 )
1584
- | TypeParameter {attrs; locs = newtypes ; pos = start_pos } ->
1585
- ( term_param_num,
1586
- make_newtypes ~attrs ~loc: (mk_loc start_pos end_pos) newtypes expr,
1587
- arity ))
1588
- parameters
1589
- (List. length term_parameters, body, 1 )
1602
+ (fun parameter (term_param_num , expr ) ->
1603
+ let {attrs; p_label = lbl; expr = default_expr; pat; p_pos = start_pos}
1604
+ =
1605
+ parameter
1606
+ in
1607
+ let loc = mk_loc start_pos end_pos in
1608
+ let fun_expr =
1609
+ Ast_helper.Exp. fun_ ~loc ~attrs ~arity: None lbl default_expr pat expr
1610
+ in
1611
+ if term_param_num = 1 then
1612
+ ( term_param_num - 1 ,
1613
+ Ast_uncurried. uncurried_fun
1614
+ ~arity: (List. length term_parameters)
1615
+ fun_expr )
1616
+ else (term_param_num - 1 , fun_expr))
1617
+ term_parameters
1618
+ (List. length term_parameters, body)
1619
+ in
1620
+ let arrow_expr =
1621
+ match type_param_opt with
1622
+ | None -> arrow_expr
1623
+ | Some {attrs; locs = newtypes ; p_pos = start_pos } ->
1624
+ make_newtypes ~attrs ~loc: (mk_loc start_pos end_pos) newtypes arrow_expr
1590
1625
in
1591
1626
{arrow_expr with pexp_loc = {arrow_expr.pexp_loc with loc_start = start_pos}}
1592
1627
@@ -1620,7 +1655,7 @@ and parse_parameter p =
1620
1655
if p.Parser. token = Typ then (
1621
1656
Parser. next p;
1622
1657
let lidents = parse_lident_list p in
1623
- Some (TypeParameter {attrs; locs = lidents; pos = start_pos}))
1658
+ Some (TypeParameter {attrs; locs = lidents; p_pos = start_pos}))
1624
1659
else
1625
1660
let attrs, lbl, pat =
1626
1661
match p.Parser. token with
@@ -1694,15 +1729,17 @@ and parse_parameter p =
1694
1729
Parser. next p;
1695
1730
Some
1696
1731
(TermParameter
1697
- {attrs; label = lbl; expr = None ; pat; pos = start_pos})
1732
+ {attrs; p_label = lbl; expr = None ; pat; p_pos = start_pos})
1698
1733
| _ ->
1699
1734
let expr = parse_constrained_or_coerced_expr p in
1700
1735
Some
1701
1736
(TermParameter
1702
- {attrs; label = lbl; expr = Some expr; pat; pos = start_pos}))
1737
+ {attrs; p_label = lbl; expr = Some expr; pat; p_pos = start_pos})
1738
+ )
1703
1739
| _ ->
1704
1740
Some
1705
- (TermParameter {attrs; label = lbl; expr = None ; pat; pos = start_pos})
1741
+ (TermParameter
1742
+ {attrs; p_label = lbl; expr = None ; pat; p_pos = start_pos})
1706
1743
else None
1707
1744
1708
1745
and parse_parameter_list p =
@@ -1711,12 +1748,7 @@ and parse_parameter_list p =
1711
1748
~f: parse_parameter ~closing: Rparen p
1712
1749
in
1713
1750
Parser. expect Rparen p;
1714
- let has_term_parameter =
1715
- Ext_list. exists parameters (function
1716
- | TermParameter _ -> true
1717
- | _ -> false )
1718
- in
1719
- (has_term_parameter, parameters)
1751
+ extract_fundef_params ~type_acc: None ~term_acc: [] parameters
1720
1752
1721
1753
(* parameters ::=
1722
1754
* | _
@@ -1725,7 +1757,7 @@ and parse_parameter_list p =
1725
1757
* | (.)
1726
1758
* | ( parameter {, parameter} [,] )
1727
1759
*)
1728
- and parse_parameters p =
1760
+ and parse_parameters p : fundef_type_param option * fundef_term_param list =
1729
1761
let start_pos = p.Parser. start_pos in
1730
1762
let unit_term_parameter () =
1731
1763
let loc = mk_loc start_pos p.Parser. prev_end_pos in
@@ -1734,51 +1766,52 @@ and parse_parameters p =
1734
1766
(Location. mkloc (Longident. Lident " ()" ) loc)
1735
1767
None
1736
1768
in
1737
- TermParameter
1738
- {
1739
- attrs = [] ;
1740
- label = Asttypes. Nolabel ;
1741
- expr = None ;
1742
- pat = unit_pattern;
1743
- pos = start_pos;
1744
- }
1769
+ {
1770
+ attrs = [] ;
1771
+ p_label = Asttypes. Nolabel ;
1772
+ expr = None ;
1773
+ pat = unit_pattern;
1774
+ p_pos = start_pos;
1775
+ }
1745
1776
in
1746
1777
match p.Parser. token with
1747
1778
| Lident ident ->
1748
1779
Parser. next p;
1749
1780
let loc = mk_loc start_pos p.Parser. prev_end_pos in
1750
- [
1751
- TermParameter
1781
+ ( None ,
1782
+ [
1752
1783
{
1753
1784
attrs = [] ;
1754
- label = Asttypes. Nolabel ;
1785
+ p_label = Asttypes. Nolabel ;
1755
1786
expr = None ;
1756
1787
pat = Ast_helper.Pat. var ~loc (Location. mkloc ident loc);
1757
- pos = start_pos;
1788
+ p_pos = start_pos;
1758
1789
};
1759
- ]
1790
+ ] )
1760
1791
| Underscore ->
1761
1792
Parser. next p;
1762
1793
let loc = mk_loc start_pos p.Parser. prev_end_pos in
1763
- [
1764
- TermParameter
1794
+ ( None ,
1795
+ [
1765
1796
{
1766
1797
attrs = [] ;
1767
- label = Asttypes. Nolabel ;
1798
+ p_label = Asttypes. Nolabel ;
1768
1799
expr = None ;
1769
1800
pat = Ast_helper.Pat. any ~loc () ;
1770
- pos = start_pos;
1801
+ p_pos = start_pos;
1771
1802
};
1772
- ]
1803
+ ] )
1773
1804
| Lparen ->
1774
1805
Parser. next p;
1775
1806
ignore (Parser. optional p Dot );
1776
- let has_term_parameter, parameters = parse_parameter_list p in
1777
- if has_term_parameter then parameters
1778
- else parameters @ [unit_term_parameter () ]
1807
+ let type_params, term_params = parse_parameter_list p in
1808
+ let term_params =
1809
+ if term_params <> [] then term_params else [unit_term_parameter () ]
1810
+ in
1811
+ (type_params, term_params)
1779
1812
| token ->
1780
1813
Parser. err p (Diagnostics. unexpected token p.breadcrumbs);
1781
- []
1814
+ ( None , [] )
1782
1815
1783
1816
and parse_coerced_expr ~(expr : Parsetree.expression ) p =
1784
1817
Parser. expect ColonGreaterThan p;
@@ -2974,16 +3007,15 @@ and parse_braced_or_record_expr p =
2974
3007
let ident = Location. mkloc (Longident. last path_ident.txt) loc in
2975
3008
let a =
2976
3009
parse_es6_arrow_expression
2977
- ~parameters :
3010
+ ~term_parameters :
2978
3011
[
2979
- TermParameter
2980
- {
2981
- attrs = [] ;
2982
- label = Asttypes. Nolabel ;
2983
- expr = None ;
2984
- pat = Ast_helper.Pat. var ~loc: ident.loc ident;
2985
- pos = start_pos;
2986
- };
3012
+ {
3013
+ attrs = [] ;
3014
+ p_label = Asttypes. Nolabel ;
3015
+ expr = None ;
3016
+ pat = Ast_helper.Pat. var ~loc: ident.loc ident;
3017
+ p_pos = start_pos;
3018
+ };
2987
3019
]
2988
3020
p
2989
3021
in
0 commit comments