Skip to content

Commit

Permalink
[display] add FinalFields cause to generate missing ctors
Browse files Browse the repository at this point in the history
  • Loading branch information
Simn committed Aug 17, 2020
1 parent 3510b11 commit 10e5eb7
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 10 deletions.
1 change: 1 addition & 0 deletions src/context/common.ml
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ type missing_field_cause =
| ImplementedInterface of tclass * tparams
| PropertyAccessor of tclass_field * bool (* true = getter *)
| FieldAccess
| FinalFields of tclass_field list

and missing_fields_diagnostics = {
mf_pos : pos;
Expand Down
4 changes: 4 additions & 0 deletions src/context/display/diagnosticsPrinter.ml
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ let json_of_diagnostics dctx =
]
| FieldAccess ->
"FieldAccess",jobject []
| FinalFields cfl ->
"FinalFields",jobject [
"fields",jarray (List.map (fun cf -> generate_class_field jctx (scope cf) cf) cfl)
]
in
let current_fields = ref [] in
let map_field (cf,t,ct) =
Expand Down
33 changes: 23 additions & 10 deletions src/typing/typeloadFields.ml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ type class_init_ctx = {
mutable has_display_field : bool;
mutable delayed_expr : (typer * tlazy ref option) list;
mutable force_constructor : bool;
mutable uninitialized_final : pos option;
mutable uninitialized_final : tclass_field list;
}

type field_kind =
Expand Down Expand Up @@ -538,7 +538,7 @@ let create_class_context ctx c context_init p =
abstract = abstract;
context_init = context_init;
force_constructor = false;
uninitialized_final = None;
uninitialized_final = [];
delayed_expr = [];
has_display_field = false;
} in
Expand Down Expand Up @@ -943,10 +943,6 @@ let create_variable (ctx,cctx,fctx) c f t eo p =
if fctx.is_abstract_member && not is_abstract_enum_field then error (fst f.cff_name ^ ": Cannot declare member variable in abstract") p;
if fctx.is_inline && not fctx.is_static then error (fst f.cff_name ^ ": Inline variable must be static") p;
if fctx.is_inline && eo = None then error (fst f.cff_name ^ ": Inline variable must be initialized") p;
if fctx.is_final && not (fctx.is_extern || (has_class_flag c CExtern) || (has_class_flag c CInterface)) && eo = None then begin
if fctx.is_static then error (fst f.cff_name ^ ": Static final variable must be initialized") p
else cctx.uninitialized_final <- Some f.cff_pos;
end;
let t = (match t with
| None when eo = None ->
error ("Variable requires type-hint or initialization") (pos f.cff_name);
Expand All @@ -968,7 +964,13 @@ let create_variable (ctx,cctx,fctx) c f t eo p =
cf_meta = f.cff_meta;
cf_kind = Var kind;
} in
if fctx.is_final then add_class_field_flag cf CfFinal;
if fctx.is_final then begin
if not (fctx.is_extern || (has_class_flag c CExtern) || (has_class_flag c CInterface)) && eo = None then begin
if fctx.is_static then error (fst f.cff_name ^ ": Static final variable must be initialized") p
else cctx.uninitialized_final <- cf :: cctx.uninitialized_final;
end;
add_class_field_flag cf CfFinal;
end;
if fctx.is_extern then add_class_field_flag cf CfExtern;
if fctx.is_abstract_member then begin
cf.cf_meta <- ((Meta.Custom ":impl"),[],null_pos) :: cf.cf_meta;
Expand Down Expand Up @@ -1676,9 +1678,20 @@ let init_class ctx c p context_init herits fields =
else
ensure_struct_init_constructor ctx c fields p;
begin match cctx.uninitialized_final with
| Some pf when c.cl_constructor = None ->
display_error ctx "This class has uninitialized final vars, which requires a constructor" p;
display_error ctx "Example of an uninitialized final var" pf;
| cf :: cfl when c.cl_constructor = None ->
if Diagnostics.is_diagnostics_run ctx.com cf.cf_name_pos then begin
let diag = {
mf_pos = c.cl_name_pos;
mf_on = TClassDecl c;
mf_fields = [];
mf_cause = FinalFields (cf :: cfl);
} in
let display = ctx.com.display_information in
display.module_diagnostics <- MissingFields diag :: display.module_diagnostics
end else begin
display_error ctx "This class has uninitialized final vars, which requires a constructor" p;
display_error ctx "Example of an uninitialized final var" cf.cf_name_pos;
end
| _ ->
()
end;
Expand Down

0 comments on commit 10e5eb7

Please sign in to comment.