@@ -3974,7 +3974,7 @@ and parse_array_exp p =
3974
3974
3975
3975
(* TODO: check attributes in the case of poly type vars,
3976
3976
* might be context dependend: parseFieldDeclaration (see ocaml) *)
3977
- and parse_poly_type_expr p =
3977
+ and parse_poly_type_expr ? current_type_name_path ? inline_types p =
3978
3978
let start_pos = p.Parser. start_pos in
3979
3979
match p.Parser. token with
3980
3980
| SingleQuote -> (
@@ -4000,7 +4000,7 @@ and parse_poly_type_expr p =
4000
4000
Ast_helper.Typ. arrow ~loc ~arity: (Some 1 ) Nolabel typ return_type
4001
4001
| _ -> Ast_helper.Typ. var ~loc: var.loc var.txt)
4002
4002
| _ -> assert false )
4003
- | _ -> parse_typ_expr p
4003
+ | _ -> parse_typ_expr ?current_type_name_path ?inline_types p
4004
4004
4005
4005
(* 'a 'b 'c *)
4006
4006
and parse_type_var_list p =
@@ -4028,7 +4028,7 @@ and parse_lident_list p =
4028
4028
in
4029
4029
loop p []
4030
4030
4031
- and parse_atomic_typ_expr ~attrs p =
4031
+ and parse_atomic_typ_expr ? current_type_name_path ? inline_types ~attrs p =
4032
4032
Parser. leave_breadcrumb p Grammar. AtomicTypExpr ;
4033
4033
let start_pos = p.Parser. start_pos in
4034
4034
let typ =
@@ -4085,7 +4085,8 @@ and parse_atomic_typ_expr ~attrs p =
4085
4085
let extension = parse_extension p in
4086
4086
let loc = mk_loc start_pos p.prev_end_pos in
4087
4087
Ast_helper.Typ. extension ~attrs ~loc extension
4088
- | Lbrace -> parse_record_or_object_type ~attrs p
4088
+ | Lbrace ->
4089
+ parse_record_or_object_type ?current_type_name_path ?inline_types ~attrs p
4089
4090
| Eof ->
4090
4091
Parser. err p (Diagnostics. unexpected p.Parser. token p.breadcrumbs);
4091
4092
Recover. default_type ()
@@ -4147,7 +4148,7 @@ and parse_package_constraint p =
4147
4148
Some (type_constr, typ)
4148
4149
| _ -> None
4149
4150
4150
- and parse_record_or_object_type ~attrs p =
4151
+ and parse_record_or_object_type ? current_type_name_path ? inline_types ~attrs p =
4151
4152
(* for inline record in constructor *)
4152
4153
let start_pos = p.Parser. start_pos in
4153
4154
Parser. expect Lbrace p;
@@ -4161,20 +4162,39 @@ and parse_record_or_object_type ~attrs p =
4161
4162
Asttypes. Closed
4162
4163
| _ -> Asttypes. Closed
4163
4164
in
4164
- let () =
4165
- match p.token with
4166
- | Lident _ ->
4167
- Parser. err p
4168
- (Diagnostics. message ErrorMessages. forbidden_inline_record_declaration)
4169
- | _ -> ()
4170
- in
4171
- let fields =
4172
- parse_comma_delimited_region ~grammar: Grammar. StringFieldDeclarations
4173
- ~closing: Rbrace ~f: parse_string_field_declaration p
4174
- in
4175
- Parser. expect Rbrace p;
4176
- let loc = mk_loc start_pos p.prev_end_pos in
4177
- Ast_helper.Typ. object_ ~loc ~attrs fields closed_flag
4165
+ match (p.token, inline_types, current_type_name_path) with
4166
+ | Lident _ , Some inline_types , Some current_type_name_path ->
4167
+ let labels =
4168
+ parse_comma_delimited_region ~grammar: Grammar. RecordDecl ~closing: Rbrace
4169
+ ~f:
4170
+ (parse_field_declaration_region ~current_type_name_path ~inline_types )
4171
+ p
4172
+ in
4173
+ Parser. expect Rbrace p;
4174
+ let loc = mk_loc start_pos p.prev_end_pos in
4175
+ let inline_type_name = current_type_name_path |> String. concat " ." in
4176
+ inline_types :=
4177
+ (inline_type_name, loc, Parsetree. Ptype_record labels) :: ! inline_types;
4178
+
4179
+ let lid = Location. mkloc (Longident. Lident inline_type_name) loc in
4180
+ Ast_helper.Typ. constr
4181
+ ~attrs: [(Location. mknoloc " inlineRecordReference" , PStr [] )]
4182
+ ~loc lid []
4183
+ | _ ->
4184
+ let () =
4185
+ match p.token with
4186
+ | Lident _ ->
4187
+ Parser. err p
4188
+ (Diagnostics. message ErrorMessages. forbidden_inline_record_declaration)
4189
+ | _ -> ()
4190
+ in
4191
+ let fields =
4192
+ parse_comma_delimited_region ~grammar: Grammar. StringFieldDeclarations
4193
+ ~closing: Rbrace ~f: parse_string_field_declaration p
4194
+ in
4195
+ Parser. expect Rbrace p;
4196
+ let loc = mk_loc start_pos p.prev_end_pos in
4197
+ Ast_helper.Typ. object_ ~loc ~attrs fields closed_flag
4178
4198
4179
4199
(* TODO: check associativity in combination with attributes *)
4180
4200
and parse_type_alias p typ =
@@ -4374,7 +4394,8 @@ and parse_es6_arrow_type ~attrs p =
4374
4394
* | uident.lident
4375
4395
* | uident.uident.lident --> long module path
4376
4396
*)
4377
- and parse_typ_expr ?attrs ?(es6_arrow = true ) ?(alias = true ) p =
4397
+ and parse_typ_expr ?current_type_name_path ?inline_types ?attrs
4398
+ ?(es6_arrow = true ) ?(alias = true ) p =
4378
4399
(* Parser.leaveBreadcrumb p Grammar.TypeExpression; *)
4379
4400
let start_pos = p.Parser. start_pos in
4380
4401
let attrs =
@@ -4385,7 +4406,9 @@ and parse_typ_expr ?attrs ?(es6_arrow = true) ?(alias = true) p =
4385
4406
let typ =
4386
4407
if es6_arrow && is_es6_arrow_type p then parse_es6_arrow_type ~attrs p
4387
4408
else
4388
- let typ = parse_atomic_typ_expr ~attrs p in
4409
+ let typ =
4410
+ parse_atomic_typ_expr ?current_type_name_path ?inline_types ~attrs p
4411
+ in
4389
4412
parse_arrow_type_rest ~es6_arrow ~start_pos typ p
4390
4413
in
4391
4414
let typ = if alias then parse_type_alias p typ else typ in
@@ -4526,7 +4549,8 @@ and parse_field_declaration p =
4526
4549
let loc = mk_loc start_pos typ.ptyp_loc.loc_end in
4527
4550
Ast_helper.Type. field ~attrs ~loc ~mut ~optional name typ
4528
4551
4529
- and parse_field_declaration_region ?found_object_field p =
4552
+ and parse_field_declaration_region ?current_type_name_path ?inline_types
4553
+ ?found_object_field p =
4530
4554
let start_pos = p.Parser. start_pos in
4531
4555
let attrs = parse_attributes p in
4532
4556
let mut =
@@ -4551,12 +4575,17 @@ and parse_field_declaration_region ?found_object_field p =
4551
4575
| Lident _ ->
4552
4576
let lident, loc = parse_lident p in
4553
4577
let name = Location. mkloc lident loc in
4578
+ let current_type_name_path =
4579
+ match current_type_name_path with
4580
+ | None -> None
4581
+ | Some current_type_name_path -> Some (current_type_name_path @ [name.txt])
4582
+ in
4554
4583
let optional = parse_optional_label p in
4555
4584
let typ =
4556
4585
match p.Parser. token with
4557
4586
| Colon ->
4558
4587
Parser. next p;
4559
- parse_poly_type_expr p
4588
+ parse_poly_type_expr ?current_type_name_path ?inline_types p
4560
4589
| _ ->
4561
4590
Ast_helper.Typ. constr ~loc: name.loc ~attrs
4562
4591
{name with txt = Lident name.txt}
@@ -4582,12 +4611,13 @@ and parse_field_declaration_region ?found_object_field p =
4582
4611
* | { field-decl, field-decl }
4583
4612
* | { field-decl, field-decl, field-decl, }
4584
4613
*)
4585
- and parse_record_declaration p =
4614
+ and parse_record_declaration ? current_type_name_path ? inline_types p =
4586
4615
Parser. leave_breadcrumb p Grammar. RecordDecl ;
4587
4616
Parser. expect Lbrace p;
4588
4617
let rows =
4589
4618
parse_comma_delimited_region ~grammar: Grammar. RecordDecl ~closing: Rbrace
4590
- ~f: parse_field_declaration_region p
4619
+ ~f: (parse_field_declaration_region ?current_type_name_path ?inline_types)
4620
+ p
4591
4621
in
4592
4622
Parser. expect Rbrace p;
4593
4623
Parser. eat_breadcrumb p;
@@ -4830,7 +4860,7 @@ and parse_type_constructor_declarations ?first p =
4830
4860
* ∣ = private record-decl
4831
4861
* | = ..
4832
4862
*)
4833
- and parse_type_representation p =
4863
+ and parse_type_representation ? current_type_name_path ? inline_types p =
4834
4864
Parser. leave_breadcrumb p Grammar. TypeRepresentation ;
4835
4865
(* = consumed *)
4836
4866
let private_flag =
@@ -4841,7 +4871,9 @@ and parse_type_representation p =
4841
4871
match p.Parser. token with
4842
4872
| Bar | Uident _ ->
4843
4873
Parsetree. Ptype_variant (parse_type_constructor_declarations p)
4844
- | Lbrace -> Parsetree. Ptype_record (parse_record_declaration p)
4874
+ | Lbrace ->
4875
+ Parsetree. Ptype_record
4876
+ (parse_record_declaration ?current_type_name_path ?inline_types p)
4845
4877
| DotDot ->
4846
4878
Parser. next p;
4847
4879
Ptype_open
@@ -5032,7 +5064,7 @@ and parse_type_equation_or_constr_decl p =
5032
5064
(* TODO: is this a good idea? *)
5033
5065
(None , Asttypes. Public , Parsetree. Ptype_abstract )
5034
5066
5035
- and parse_record_or_object_decl p =
5067
+ and parse_record_or_object_decl ? current_type_name_path ? inline_types p =
5036
5068
let start_pos = p.Parser. start_pos in
5037
5069
Parser. expect Lbrace p;
5038
5070
match p.Parser. token with
@@ -5088,7 +5120,9 @@ and parse_record_or_object_decl p =
5088
5120
let found_object_field = ref false in
5089
5121
let fields =
5090
5122
parse_comma_delimited_region ~grammar: Grammar. RecordDecl ~closing: Rbrace
5091
- ~f: (parse_field_declaration_region ~found_object_field )
5123
+ ~f:
5124
+ (parse_field_declaration_region ?current_type_name_path
5125
+ ?inline_types ~found_object_field )
5092
5126
p
5093
5127
in
5094
5128
Parser. expect Rbrace p;
@@ -5159,7 +5193,11 @@ and parse_record_or_object_decl p =
5159
5193
match attrs with
5160
5194
| [] ->
5161
5195
parse_comma_delimited_region ~grammar: Grammar. FieldDeclarations
5162
- ~closing: Rbrace ~f: parse_field_declaration_region p
5196
+ ~closing: Rbrace
5197
+ ~f:
5198
+ (parse_field_declaration_region ?current_type_name_path
5199
+ ?inline_types)
5200
+ p
5163
5201
| attr :: _ as attrs ->
5164
5202
let first =
5165
5203
let field = parse_field_declaration p in
@@ -5176,7 +5214,11 @@ and parse_record_or_object_decl p =
5176
5214
in
5177
5215
first
5178
5216
:: parse_comma_delimited_region ~grammar: Grammar. FieldDeclarations
5179
- ~closing: Rbrace ~f: parse_field_declaration_region p
5217
+ ~closing: Rbrace
5218
+ ~f:
5219
+ (parse_field_declaration_region ?current_type_name_path
5220
+ ?inline_types)
5221
+ p
5180
5222
in
5181
5223
Parser. expect Rbrace p;
5182
5224
Parser. eat_breadcrumb p;
@@ -5366,14 +5408,16 @@ and parse_polymorphic_variant_type_args p =
5366
5408
| [typ] -> typ
5367
5409
| types -> Ast_helper.Typ. tuple ~loc ~attrs types
5368
5410
5369
- and parse_type_equation_and_representation p =
5411
+ and parse_type_equation_and_representation ?current_type_name_path ?inline_types
5412
+ p =
5370
5413
match p.Parser. token with
5371
5414
| (Equal | Bar ) as token -> (
5372
5415
if token = Bar then Parser. expect Equal p;
5373
5416
Parser. next p;
5374
5417
match p.Parser. token with
5375
5418
| Uident _ -> parse_type_equation_or_constr_decl p
5376
- | Lbrace -> parse_record_or_object_decl p
5419
+ | Lbrace ->
5420
+ parse_record_or_object_decl ?current_type_name_path ?inline_types p
5377
5421
| Private -> parse_private_eq_or_repr p
5378
5422
| Bar | DotDot ->
5379
5423
let priv, kind = parse_type_representation p in
@@ -5383,7 +5427,9 @@ and parse_type_equation_and_representation p =
5383
5427
match p.Parser. token with
5384
5428
| Equal ->
5385
5429
Parser. next p;
5386
- let priv, kind = parse_type_representation p in
5430
+ let priv, kind =
5431
+ parse_type_representation ?current_type_name_path ?inline_types p
5432
+ in
5387
5433
(manifest, priv, kind)
5388
5434
| _ -> (manifest, Public , Parsetree. Ptype_abstract )))
5389
5435
| _ -> (None , Public , Parsetree. Ptype_abstract )
@@ -5449,9 +5495,13 @@ and parse_type_extension ~params ~attrs ~name p =
5449
5495
let constructors = loop p [first] in
5450
5496
Ast_helper.Te. mk ~attrs ~params ~priv name constructors
5451
5497
5452
- and parse_type_definitions ~attrs ~name ~params ~start_pos p =
5498
+ and parse_type_definitions ?current_type_name_path ?inline_types ~attrs ~name
5499
+ ~params ~start_pos p =
5453
5500
let type_def =
5454
- let manifest, priv, kind = parse_type_equation_and_representation p in
5501
+ let manifest, priv, kind =
5502
+ parse_type_equation_and_representation ?current_type_name_path
5503
+ ?inline_types p
5504
+ in
5455
5505
let cstrs = parse_type_constraints p in
5456
5506
let loc = mk_loc start_pos p.prev_end_pos in
5457
5507
Ast_helper.Type. mk ~loc ~attrs ~priv ~kind ~params ~cstrs ?manifest
@@ -5500,8 +5550,24 @@ and parse_type_definition_or_extension ~attrs p =
5500
5550
(longident |> ErrorMessages. type_declaration_name_longident
5501
5551
|> Diagnostics. message)
5502
5552
in
5503
- let type_defs = parse_type_definitions ~attrs ~name ~params ~start_pos p in
5504
- TypeDef {rec_flag; types = type_defs}
5553
+ let current_type_name_path = Longident. flatten name.txt in
5554
+ let inline_types = ref [] in
5555
+ let type_defs =
5556
+ parse_type_definitions ~inline_types ~current_type_name_path ~attrs ~name
5557
+ ~params ~start_pos p
5558
+ in
5559
+ let rec_flag =
5560
+ if List. length ! inline_types > 0 then Asttypes. Recursive else rec_flag
5561
+ in
5562
+ let inline_types =
5563
+ ! inline_types
5564
+ |> List. map (fun (inline_type_name , loc , kind ) ->
5565
+ Ast_helper.Type. mk
5566
+ ~attrs: [(Location. mknoloc " inlineRecordDefinition" , PStr [] )]
5567
+ ~loc ~kind
5568
+ {name with txt = inline_type_name})
5569
+ in
5570
+ TypeDef {rec_flag; types = inline_types @ type_defs}
5505
5571
5506
5572
(* external value-name : typexp = external-declaration *)
5507
5573
and parse_external_def ~attrs ~start_pos p =
0 commit comments