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