@@ -182,26 +182,53 @@ type typ_def_or_ext =
182182 }
183183 | TypeExt of Parsetree .type_extension
184184
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
198203
199204type record_pattern_item =
200205 | PatUnderscore
201206 | PatField of (Ast_helper .lid * Parsetree .pattern * bool (* optional *) )
202207
203208type context = OrdinaryExpr | TernaryTrueBranchExpr | WhenExpr
204209
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+
205232let get_closing_token = function
206233 | Token. Lparen -> Token. Rparen
207234 | Lbrace -> Rbrace
@@ -1510,7 +1537,7 @@ and parse_ternary_expr left_operand p =
15101537 | _ -> left_operand
15111538
15121539and parse_es6_arrow_expression ?(arrow_attrs = [] ) ?(arrow_start_pos = None )
1513- ?context ?parameters p =
1540+ ?context ?term_parameters p =
15141541 let start_pos = p.Parser. start_pos in
15151542 Parser. leave_breadcrumb p Grammar. Es6ArrowExpr ;
15161543 (* Parsing function parameters and attributes:
@@ -1520,8 +1547,8 @@ and parse_es6_arrow_expression ?(arrow_attrs = []) ?(arrow_start_pos = None)
15201547 2. Attributes inside `(...)` are added to the arguments regardless of whether
15211548 labeled, optional or nolabeled *)
15221549 let parameters =
1523- match parameters with
1524- | Some params -> params
1550+ match term_parameters with
1551+ | Some params -> ( None , params)
15251552 | None -> parse_parameters p
15261553 in
15271554 let parameters =
@@ -1532,15 +1559,23 @@ and parse_es6_arrow_expression ?(arrow_attrs = []) ?(arrow_start_pos = None)
15321559 | None -> pos
15331560 in
15341561 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
15441579 in
15451580 let return_type =
15461581 match p.Parser. token with
@@ -1561,32 +1596,32 @@ and parse_es6_arrow_expression ?(arrow_attrs = []) ?(arrow_start_pos = None)
15611596 in
15621597 Parser. eat_breadcrumb p;
15631598 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 =
15711601 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
15901625 in
15911626 {arrow_expr with pexp_loc = {arrow_expr.pexp_loc with loc_start = start_pos}}
15921627
@@ -1620,7 +1655,7 @@ and parse_parameter p =
16201655 if p.Parser. token = Typ then (
16211656 Parser. next p;
16221657 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}))
16241659 else
16251660 let attrs, lbl, pat =
16261661 match p.Parser. token with
@@ -1694,15 +1729,17 @@ and parse_parameter p =
16941729 Parser. next p;
16951730 Some
16961731 (TermParameter
1697- {attrs; label = lbl; expr = None ; pat; pos = start_pos})
1732+ {attrs; p_label = lbl; expr = None ; pat; p_pos = start_pos})
16981733 | _ ->
16991734 let expr = parse_constrained_or_coerced_expr p in
17001735 Some
17011736 (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+ )
17031739 | _ ->
17041740 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})
17061743 else None
17071744
17081745and parse_parameter_list p =
@@ -1711,12 +1748,7 @@ and parse_parameter_list p =
17111748 ~f: parse_parameter ~closing: Rparen p
17121749 in
17131750 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
17201752
17211753(* parameters ::=
17221754 * | _
@@ -1725,7 +1757,7 @@ and parse_parameter_list p =
17251757 * | (.)
17261758 * | ( parameter {, parameter} [,] )
17271759 *)
1728- and parse_parameters p =
1760+ and parse_parameters p : fundef_type_param option * fundef_term_param list =
17291761 let start_pos = p.Parser. start_pos in
17301762 let unit_term_parameter () =
17311763 let loc = mk_loc start_pos p.Parser. prev_end_pos in
@@ -1734,51 +1766,52 @@ and parse_parameters p =
17341766 (Location. mkloc (Longident. Lident " ()" ) loc)
17351767 None
17361768 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+ }
17451776 in
17461777 match p.Parser. token with
17471778 | Lident ident ->
17481779 Parser. next p;
17491780 let loc = mk_loc start_pos p.Parser. prev_end_pos in
1750- [
1751- TermParameter
1781+ ( None ,
1782+ [
17521783 {
17531784 attrs = [] ;
1754- label = Asttypes. Nolabel ;
1785+ p_label = Asttypes. Nolabel ;
17551786 expr = None ;
17561787 pat = Ast_helper.Pat. var ~loc (Location. mkloc ident loc);
1757- pos = start_pos;
1788+ p_pos = start_pos;
17581789 };
1759- ]
1790+ ] )
17601791 | Underscore ->
17611792 Parser. next p;
17621793 let loc = mk_loc start_pos p.Parser. prev_end_pos in
1763- [
1764- TermParameter
1794+ ( None ,
1795+ [
17651796 {
17661797 attrs = [] ;
1767- label = Asttypes. Nolabel ;
1798+ p_label = Asttypes. Nolabel ;
17681799 expr = None ;
17691800 pat = Ast_helper.Pat. any ~loc () ;
1770- pos = start_pos;
1801+ p_pos = start_pos;
17711802 };
1772- ]
1803+ ] )
17731804 | Lparen ->
17741805 Parser. next p;
17751806 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)
17791812 | token ->
17801813 Parser. err p (Diagnostics. unexpected token p.breadcrumbs);
1781- []
1814+ ( None , [] )
17821815
17831816and parse_coerced_expr ~(expr : Parsetree.expression ) p =
17841817 Parser. expect ColonGreaterThan p;
@@ -2974,16 +3007,15 @@ and parse_braced_or_record_expr p =
29743007 let ident = Location. mkloc (Longident. last path_ident.txt) loc in
29753008 let a =
29763009 parse_es6_arrow_expression
2977- ~parameters :
3010+ ~term_parameters :
29783011 [
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+ };
29873019 ]
29883020 p
29893021 in
0 commit comments