@@ -281,6 +281,7 @@ let reify in_macro =
281281 | CTParent t -> ct " TParent" [to_type_hint t p]
282282 | CTExtend (tl ,fields ) -> ct " TExtend" [to_array to_tpath tl p; to_array to_cfield fields p]
283283 | CTOptional t -> ct " TOptional" [to_type_hint t p]
284+ | CTNamed (n ,t ) -> ct " TNamed" [to_placed_name n; to_type_hint t p]
284285 and to_type_hint (t ,p ) _ =
285286 (* to_obj ["type",to_ctype t p;"pos",to_pos p] p *)
286287 to_ctype (t,p) p
@@ -911,7 +912,7 @@ and parse_type_opt = parser
911912 | [< t = parse_type_hint >] -> Some t
912913 | [< >] -> None
913914
914- and parse_complex_type s =
915+ and parse_complex_type ?( allow_named = false ) s =
915916 let t = parse_complex_type_inner s in
916917 parse_complex_type_next t s
917918
@@ -920,7 +921,16 @@ and parse_structural_extension = parser
920921 t
921922
922923and parse_complex_type_inner = parser
923- | [< '(POpen ,p1); t = parse_complex_type; '(PClose ,p2) >] -> CTParent t,punion p1 p2
924+ | [< '(POpen ,p1); tl = psep Comma (parse_complex_type ~allow_named: true ); '(PClose ,p2); s >] ->
925+ let arg_error p = error (Custom " Unnamed function arguments are not supported" ) p in
926+ (match tl with
927+ | [] as rest | ((CTOptional (CTNamed _ ,_ ) | CTNamed _ ), _ ) :: rest ->
928+ List. iter (fun (t ,p ) -> match t with (CTNamed _ | CTOptional (CTNamed _ ,_ )) -> () | _ -> arg_error p) rest;
929+ let t = parse_ctfunction_rest p1 tl s in
930+ CTParent t,pos t (* wrap in parens to prevent CTFunction merging *)
931+ | [t] ->
932+ CTParent t,punion p1 p2
933+ | _ -> arg_error (punion p1 p2))
924934 | [< '(BrOpen ,p1); s >] ->
925935 (match s with parser
926936 | [< l,p2 = parse_type_anonymous false >] -> CTAnonymous l,punion p1 p2
@@ -933,49 +943,66 @@ and parse_complex_type_inner = parser
933943 | [< >] -> serror() )
934944 | [< '(Question ,p1); t,p2 = parse_complex_type_inner >] ->
935945 CTOptional (t,p2),punion p1 p2
946+ | [< n = dollar_ident; s >] ->
947+ (match s with parser
948+ | [< '(DblDot ,_); t = parse_complex_type >] ->
949+ let p1 = snd n in
950+ let p2 = snd t in
951+ CTNamed (n,t),punion p1 p2
952+ | [< s >] ->
953+ let n,p = n in
954+ let t,p = parse_type_path2 None [] n p s in
955+ CTPath t,p)
936956 | [< t,p = parse_type_path >] ->
937957 CTPath t,p
938958
959+ and parse_ctfunction_rest p1 args = parser
960+ | [< '(Arrow ,_); ret = parse_complex_type >] ->
961+ CTFunction (args,ret),punion p1 (snd ret)
962+
939963and parse_type_path s = parse_type_path1 None [] s
940964
941965and parse_type_path1 p0 pack = parser
942966 | [< name, p1 = dollar_ident_macro pack; s >] ->
943- if is_lower_ident name then
944- (match s with parser
945- | [< '(Dot ,p) >] ->
946- if is_resuming p then
947- raise (TypePath (List. rev (name :: pack),None ,false ))
948- else
949- parse_type_path1 (match p0 with None -> Some p1 | Some _ -> p0) (name :: pack) s
950- | [< '(Semicolon ,_) >] ->
951- error (Custom " Type name should start with an uppercase letter" ) p1
952- | [< >] -> serror() )
953- else
954- let sub,p2 = (match s with parser
955- | [< '(Dot ,p); s >] ->
956- (if is_resuming p then
957- raise (TypePath (List. rev pack,Some (name,false ),false ))
958- else match s with parser
959- | [< '(Const (Ident name),p2) when not (is_lower_ident name) >] -> Some name,p2
960- | [< '(Binop OpOr ,_) when do_resume() >] ->
961- set_resume p;
962- raise (TypePath (List. rev pack,Some (name,false ),false ))
963- | [< >] -> serror() )
964- | [< >] -> None ,p1
965- ) in
966- let params,p2 = (match s with parser
967- | [< '(Binop OpLt ,_); l = psep Comma parse_type_path_or_const; '(Binop OpGt ,p2) >] -> l,p2
968- | [< > ] -> [] ,p2
969- ) in
970- {
971- tpackage = List. rev pack;
972- tname = name;
973- tparams = params;
974- tsub = sub;
975- },punion (match p0 with None -> p1 | Some p -> p) p2
967+ parse_type_path2 p0 pack name p1 s
976968 | [< '(Binop OpOr ,_) when do_resume() >] ->
977969 raise (TypePath (List. rev pack,None ,false ))
978970
971+ and parse_type_path2 p0 pack name p1 s =
972+ if is_lower_ident name then
973+ (match s with parser
974+ | [< '(Dot ,p) >] ->
975+ if is_resuming p then
976+ raise (TypePath (List. rev (name :: pack),None ,false ))
977+ else
978+ parse_type_path1 (match p0 with None -> Some p1 | Some _ -> p0) (name :: pack) s
979+ | [< '(Semicolon ,_) >] ->
980+ error (Custom " Type name should start with an uppercase letter" ) p1
981+ | [< >] -> serror() )
982+ else
983+ let sub,p2 = (match s with parser
984+ | [< '(Dot ,p); s >] ->
985+ (if is_resuming p then
986+ raise (TypePath (List. rev pack,Some (name,false ),false ))
987+ else match s with parser
988+ | [< '(Const (Ident name),p2) when not (is_lower_ident name) >] -> Some name,p2
989+ | [< '(Binop OpOr ,_) when do_resume() >] ->
990+ set_resume p;
991+ raise (TypePath (List. rev pack,Some (name,false ),false ))
992+ | [< >] -> serror() )
993+ | [< >] -> None ,p1
994+ ) in
995+ let params,p2 = (match s with parser
996+ | [< '(Binop OpLt ,_); l = psep Comma parse_type_path_or_const; '(Binop OpGt ,p2) >] -> l,p2
997+ | [< > ] -> [] ,p2
998+ ) in
999+ {
1000+ tpackage = List. rev pack;
1001+ tname = name;
1002+ tparams = params;
1003+ tsub = sub;
1004+ },punion (match p0 with None -> p1 | Some p -> p) p2
1005+
9791006and type_name = parser
9801007 | [< '(Const (Ident name),p) >] ->
9811008 if is_lower_ident name then
0 commit comments