Skip to content

AST cleanup: explicit representation for optional record fields in ty… #7190

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 5 additions & 9 deletions analysis/src/ProcessCmt.ml
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ let attrsToDocstring attrs =
| None -> []
| Some docstring -> [docstring]

let mapRecordField {Types.ld_id; ld_type; ld_attributes} =
let mapRecordField {Types.ld_id; ld_type; ld_attributes; ld_optional} =
let astamp = Ident.binding_time ld_id in
let name = Ident.name ld_id in
{
stamp = astamp;
fname = Location.mknoloc name;
typ = ld_type;
optional = Res_parsetree_viewer.has_optional_attribute ld_attributes;
optional = ld_optional;
docstring =
(match ProcessAttributes.findDocAttribute ld_attributes with
| None -> []
Expand Down Expand Up @@ -259,10 +259,7 @@ let forTypeDeclaration ~env ~(exported : Exported.t)
stamp = astamp;
fname = Location.mknoloc name;
typ = f.ld_type.ctyp_type;
optional =
Res_parsetree_viewer
.has_optional_attribute
f.ld_attributes;
optional = f.ld_optional;
docstring =
(match
ProcessAttributes
Expand Down Expand Up @@ -300,16 +297,15 @@ let forTypeDeclaration ~env ~(exported : Exported.t)
ld_name = fname;
ld_type = {ctyp_type};
ld_attributes;
ld_optional;
}
->
let fstamp = Ident.binding_time ld_id in
{
stamp = fstamp;
fname;
typ = ctyp_type;
optional =
Res_parsetree_viewer.has_optional_attribute
ld_attributes;
optional = ld_optional;
docstring = attrsToDocstring ld_attributes;
deprecated =
ProcessAttributes.findDeprecatedAttribute
Expand Down
12 changes: 10 additions & 2 deletions compiler/frontend/bs_ast_mapper.ml
Original file line number Diff line number Diff line change
Expand Up @@ -500,9 +500,17 @@ let default_mapper =
~loc:(this.location this pcd_loc)
~attrs:(this.attributes this pcd_attributes));
label_declaration =
(fun this {pld_name; pld_type; pld_loc; pld_mutable; pld_attributes} ->
(fun this
{
pld_name;
pld_type;
pld_loc;
pld_mutable;
pld_optional;
pld_attributes;
} ->
Type.field (map_loc this pld_name) (this.typ this pld_type)
~mut:pld_mutable
~mut:pld_mutable ~optional:pld_optional
~loc:(this.location this pld_loc)
~attrs:(this.attributes this pld_attributes));
cases = (fun this l -> List.map (this.case this) l);
Expand Down
4 changes: 3 additions & 1 deletion compiler/ml/ast_helper.ml
Original file line number Diff line number Diff line change
Expand Up @@ -319,10 +319,12 @@ module Type = struct
pcd_attributes = attrs;
}

let field ?(loc = !default_loc) ?(attrs = []) ?(mut = Immutable) name typ =
let field ?(loc = !default_loc) ?(attrs = []) ?(mut = Immutable)
?(optional = false) name typ =
{
pld_name = name;
pld_mutable = mut;
pld_optional = optional;
pld_type = typ;
pld_loc = loc;
pld_attributes = attrs;
Expand Down
1 change: 1 addition & 0 deletions compiler/ml/ast_helper.mli
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ module Type : sig
?loc:loc ->
?attrs:attrs ->
?mut:mutable_flag ->
?optional:bool ->
str ->
core_type ->
label_declaration
Expand Down
12 changes: 10 additions & 2 deletions compiler/ml/ast_mapper.ml
Original file line number Diff line number Diff line change
Expand Up @@ -448,9 +448,17 @@ let default_mapper =
~loc:(this.location this pcd_loc)
~attrs:(this.attributes this pcd_attributes));
label_declaration =
(fun this {pld_name; pld_type; pld_loc; pld_mutable; pld_attributes} ->
(fun this
{
pld_name;
pld_type;
pld_loc;
pld_mutable;
pld_optional;
pld_attributes;
} ->
Type.field (map_loc this pld_name) (this.typ this pld_type)
~mut:pld_mutable
~mut:pld_mutable ~optional:pld_optional
~loc:(this.location this pld_loc)
~attrs:(this.attributes this pld_attributes));
cases = (fun this l -> List.map (this.case this) l);
Expand Down
7 changes: 5 additions & 2 deletions compiler/ml/ast_mapper_from0.ml
Original file line number Diff line number Diff line change
Expand Up @@ -459,10 +459,13 @@ let default_mapper =
~attrs:(this.attributes this pcd_attributes));
label_declaration =
(fun this {pld_name; pld_type; pld_loc; pld_mutable; pld_attributes} ->
let optional, attrs =
Parsetree0.get_optional_attr (this.attributes this pld_attributes)
in
Type.field (map_loc this pld_name) (this.typ this pld_type)
~mut:pld_mutable
~mut:pld_mutable ~optional
~loc:(this.location this pld_loc)
~attrs:(this.attributes this pld_attributes));
~attrs);
cases = (fun this l -> List.map (this.case this) l);
case =
(fun this {pc_lhs; pc_guard; pc_rhs} ->
Expand Down
14 changes: 12 additions & 2 deletions compiler/ml/ast_mapper_to0.ml
Original file line number Diff line number Diff line change
Expand Up @@ -455,11 +455,21 @@ let default_mapper =
~loc:(this.location this pcd_loc)
~attrs:(this.attributes this pcd_attributes));
label_declaration =
(fun this {pld_name; pld_type; pld_loc; pld_mutable; pld_attributes} ->
(fun this
{
pld_name;
pld_type;
pld_loc;
pld_mutable;
pld_optional;
pld_attributes;
} ->
Type.field (map_loc this pld_name) (this.typ this pld_type)
~mut:pld_mutable
~loc:(this.location this pld_loc)
~attrs:(this.attributes this pld_attributes));
~attrs:
(Parsetree0.add_optional_attr ~optional:pld_optional
(this.attributes this pld_attributes)));
cases = (fun this l -> List.map (this.case this) l);
case =
(fun this {pc_lhs; pc_guard; pc_rhs} ->
Expand Down
7 changes: 2 additions & 5 deletions compiler/ml/datarepr.ml
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,6 @@ let constructor_descrs ty_path decl cstrs =
if cd_args = Cstr_tuple [] then incr num_consts else incr num_nonconsts;
if cd_res = None then incr num_normal)
cstrs;
let has_optional attrs =
Ext_list.exists attrs (fun ({txt}, _) -> txt = "res.optional")
in
let rec describe_constructors idx_const idx_nonconst = function
| [] -> []
| {cd_id; cd_args; cd_res; cd_loc; cd_attributes} :: rem ->
Expand All @@ -135,8 +132,8 @@ let constructor_descrs ty_path decl cstrs =
match cd_args with
| Cstr_tuple _ -> []
| Cstr_record lbls ->
Ext_list.filter_map lbls (fun {ld_id; ld_attributes; _} ->
if has_optional ld_attributes then Some ld_id.name else None)
Ext_list.filter_map lbls (fun {ld_id; ld_optional} ->
if ld_optional then Some ld_id.name else None)
in
let existentials, cstr_args, cstr_inlined =
let representation =
Expand Down
1 change: 1 addition & 0 deletions compiler/ml/parsetree.ml
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,7 @@ and type_kind =
and label_declaration = {
pld_name: string loc;
pld_mutable: mutable_flag;
pld_optional: bool;
pld_type: core_type;
pld_loc: Location.t;
pld_attributes: attributes; (* l : T [@id1] [@id2] *)
Expand Down
14 changes: 14 additions & 0 deletions compiler/ml/parsetree0.ml
Original file line number Diff line number Diff line change
Expand Up @@ -596,3 +596,17 @@ and module_binding = {
pmb_loc: Location.t;
}
(* X = ME *)

let optional_attr = (Location.mknoloc "res.optional", Parsetree.PStr [])
let optional_attr0 = (Location.mknoloc "res.optional", PStr [])

let add_optional_attr ~optional attrs =
if optional then optional_attr0 :: attrs else attrs

let get_optional_attr attrs_ =
let remove_optional_attr attrs =
List.filter (fun a -> a <> optional_attr) attrs
in
let attrs = remove_optional_attr attrs_ in
let optional = List.length attrs <> List.length attrs_ in
(optional, attrs)
7 changes: 6 additions & 1 deletion compiler/ml/pprintast.ml
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,10 @@ let mutable_flag f = function
| Immutable -> ()
| Mutable -> pp f "mutable@;"

let optional_flag f = function
| false -> ()
| true -> pp f "?"

(* trailing space added *)
let rec_flag f rf =
match rf with
Expand Down Expand Up @@ -1137,9 +1141,10 @@ and type_def_list ctxt f (rf, l) =

and record_declaration ctxt f lbls =
let type_record_field f pld =
pp f "@[<2>%a%s:@;%a@;%a@]"
pp f "@[<2>%a%s%a:@;%a@;%a@]"
mutable_flag pld.pld_mutable
pld.pld_name.txt
optional_flag pld.pld_optional
(core_type ctxt) pld.pld_type
(attributes ctxt) pld.pld_attributes
in
Expand Down
7 changes: 2 additions & 5 deletions compiler/ml/predef.ml
Original file line number Diff line number Diff line change
Expand Up @@ -309,13 +309,10 @@ let common_initial_env add_type add_extension empty_env =
( [
{
ld_id = ident_dict_magic_field_name;
ld_attributes =
[
(Location.mknoloc "res.optional", Parsetree.PStr []);
Dict_type_helpers.dict_magic_field_attr;
];
ld_attributes = [Dict_type_helpers.dict_magic_field_attr];
ld_loc = Location.none;
ld_mutable = Immutable;
ld_optional = true;
ld_type = newgenty (Tconstr (path_option, [tvar], ref Mnil));
};
],
Expand Down
6 changes: 1 addition & 5 deletions compiler/ml/printtyp.ml
Original file line number Diff line number Diff line change
Expand Up @@ -923,11 +923,7 @@ and tree_of_constructor cd =
(name, args, Some ret, repr)

and tree_of_label l =
let opt =
l.ld_attributes
|> List.exists (fun ({txt}, _) ->
txt = "ns.optional" || txt = "res.optional")
in
let opt = l.ld_optional in
let typ =
match l.ld_type.desc with
| Tconstr (p, [t1], _) when opt && Path.same p Predef.path_option -> t1
Expand Down
1 change: 1 addition & 0 deletions compiler/ml/subst.ml
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ let label_declaration s l =
{
ld_id = l.ld_id;
ld_mutable = l.ld_mutable;
ld_optional = l.ld_optional;
ld_type = typexp s l.ld_type;
ld_loc = loc s l.ld_loc;
ld_attributes = attrs s l.ld_attributes;
Expand Down
21 changes: 9 additions & 12 deletions compiler/ml/typedecl.ml
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ let transl_labels ?record_name env closed lbls =
{
pld_name = name;
pld_mutable = mut;
pld_optional = optional;
pld_type = arg;
pld_loc = loc;
pld_attributes = attrs;
Expand All @@ -224,6 +225,7 @@ let transl_labels ?record_name env closed lbls =
ld_id = Ident.create name.txt;
ld_name = name;
ld_mutable = mut;
ld_optional = optional;
ld_type = cty;
ld_loc = loc;
ld_attributes = attrs;
Expand All @@ -242,6 +244,7 @@ let transl_labels ?record_name env closed lbls =
{
Types.ld_id = ld.ld_id;
ld_mutable = ld.ld_mutable;
ld_optional = ld.ld_optional;
ld_type = ty;
ld_loc = ld.ld_loc;
ld_attributes = ld.ld_attributes;
Expand Down Expand Up @@ -365,9 +368,6 @@ let transl_declaration ~type_record_as_object env sdecl id =
| [] -> ()
| (_, _, loc) :: _ ->
Location.prerr_warning loc Warnings.Constraint_on_gadt);
let has_optional attrs =
Ext_list.exists attrs (fun ({txt}, _) -> txt = "res.optional")
in
let scstrs =
Ext_list.map scstrs (fun ({pcd_args} as cstr) ->
match pcd_args with
Expand All @@ -378,7 +378,7 @@ let transl_declaration ~type_record_as_object env sdecl id =
pcd_args =
Pcstr_record
(Ext_list.map lds (fun ld ->
if has_optional ld.pld_attributes then
if ld.pld_optional then
let typ = ld.pld_type in
let typ =
{
Expand Down Expand Up @@ -475,6 +475,7 @@ let transl_declaration ~type_record_as_object env sdecl id =
ld_name =
Location.mkloc (Ident.name l.ld_id) l.ld_loc;
ld_mutable = l.ld_mutable;
ld_optional = l.ld_optional;
ld_type =
{
ctyp_desc = Ttyp_any;
Expand Down Expand Up @@ -531,21 +532,17 @@ let transl_declaration ~type_record_as_object env sdecl id =
Ast_untagged_variants.check_well_formed ~env ~is_untagged_def cstrs;
(Ttype_variant tcstrs, Type_variant cstrs, sdecl)
| Ptype_record lbls_ -> (
let has_optional attrs =
Ext_list.exists attrs (fun ({txt}, _) -> txt = "res.optional")
in
let optional_labels =
Ext_list.filter_map lbls_ (fun lbl ->
if has_optional lbl.pld_attributes then Some lbl.pld_name.txt
else None)
if lbl.pld_optional then Some lbl.pld_name.txt else None)
in
let lbls =
if optional_labels = [] then lbls_
else
Ext_list.map lbls_ (fun lbl ->
let typ = lbl.pld_type in
let typ =
if has_optional lbl.pld_attributes then
if lbl.pld_optional then
{
typ with
ptyp_desc =
Expand Down Expand Up @@ -575,6 +572,7 @@ let transl_declaration ~type_record_as_object env sdecl id =
ld_id = l.ld_id;
ld_name = {txt = Ident.name l.ld_id; loc = l.ld_loc};
ld_mutable = l.ld_mutable;
ld_optional = l.ld_optional;
ld_type =
{
ld_type with
Expand Down Expand Up @@ -634,8 +632,7 @@ let transl_declaration ~type_record_as_object env sdecl id =
check_duplicates sdecl.ptype_loc lbls StringSet.empty;
let optional_labels =
Ext_list.filter_map lbls (fun lbl ->
if has_optional lbl.ld_attributes then Some lbl.ld_name.txt
else None)
if lbl.ld_optional then Some lbl.ld_name.txt else None)
in
( Ttype_record lbls,
Type_record
Expand Down
1 change: 1 addition & 0 deletions compiler/ml/typedtree.ml
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@ and label_declaration = {
ld_id: Ident.t;
ld_name: string loc;
ld_mutable: mutable_flag;
ld_optional: bool;
ld_type: core_type;
ld_loc: Location.t;
ld_attributes: attribute list;
Expand Down
1 change: 1 addition & 0 deletions compiler/ml/typedtree.mli
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,7 @@ and label_declaration = {
ld_id: Ident.t;
ld_name: string loc;
ld_mutable: mutable_flag;
ld_optional: bool;
ld_type: core_type;
ld_loc: Location.t;
ld_attributes: attributes;
Expand Down
1 change: 1 addition & 0 deletions compiler/ml/types.ml
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ and record_representation =
and label_declaration = {
ld_id: Ident.t;
ld_mutable: mutable_flag;
ld_optional: bool;
ld_type: type_expr;
ld_loc: Location.t;
ld_attributes: Parsetree.attributes;
Expand Down
1 change: 1 addition & 0 deletions compiler/ml/types.mli
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ and record_representation =
and label_declaration = {
ld_id: Ident.t;
ld_mutable: mutable_flag;
ld_optional: bool;
ld_type: type_expr;
ld_loc: Location.t;
ld_attributes: Parsetree.attributes;
Expand Down
4 changes: 2 additions & 2 deletions compiler/ml/untypeast.ml
Original file line number Diff line number Diff line change
Expand Up @@ -199,8 +199,8 @@ let constructor_declaration sub cd =
let label_declaration sub ld =
let loc = sub.location sub ld.ld_loc in
let attrs = sub.attributes sub ld.ld_attributes in
Type.field ~loc ~attrs ~mut:ld.ld_mutable (map_loc sub ld.ld_name)
(sub.typ sub ld.ld_type)
Type.field ~loc ~attrs ~mut:ld.ld_mutable ~optional:ld.ld_optional
(map_loc sub ld.ld_name) (sub.typ sub ld.ld_type)

let type_extension sub tyext =
let attrs = sub.attributes sub tyext.tyext_attributes in
Expand Down
Loading
Loading