diff --git a/check/classic/classic.ref b/check/classic/classic.ref index 5ec0a5d..9bbe7ac 100644 --- a/check/classic/classic.ref +++ b/check/classic/classic.ref @@ -33,9 +33,7 @@ ./examples/docs/exported_values/hello_world/hello_world_with_intf.mli:3: goodbye ./examples/docs/exported_values/hello_world/hello_world_with_intf.mli:4: world -./examples/docs/exported_values/limitations/incl_same_name/incl_with_intf/with_intf.mli:2: unused: Should not be detected ./examples/docs/exported_values/limitations/incl_same_name/incl_with_intf/with_intf.mli:4: redefined_unused -./examples/docs/exported_values/limitations/incl_same_name/incl_with_intf/without_intf.ml:2: unused: Should not be detected ./examples/docs/exported_values/limitations/incl_same_name/incl_with_intf/without_intf.mli:4: redefined_unused ./examples/docs/exported_values/limitations/incl_same_name/incl_without_intf/with_intf.ml:4: redefined_unused @@ -183,34 +181,6 @@ Nothing else to report in this section .> UNUSED METHODS: ================= -./examples/docs/limitations/modtype/modtype_with_intf.mli:7: Ftor_with.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:7: Incl.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:7: Incl_with.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:7: With.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:8: Ftor_with.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:8: Incl.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:8: Incl_with.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:8: With.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:18: Subst.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:18: Subst.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:29: Incl_subst.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:29: Incl_subst.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:36: Ftor_subst.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:36: Ftor_subst.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:7: Ftor_with.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:7: Incl.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:7: Incl_with.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:7: With.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:8: Ftor_with.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:8: Incl.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:8: Incl_with.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:8: With.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:36: Subst.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:36: Subst.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:74: Incl_subst.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:74: Incl_subst.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:108: Ftor_subst.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:108: Ftor_subst.o#m: Should not be detected ./examples/docs/methods/code_constructs/class/class_bin.ml:2: unused_class#unused_method ./examples/docs/methods/code_constructs/class/class_lib.mli:2: int_stack#reset @@ -304,14 +274,6 @@ Nothing else to report in this section ./examples/docs/fields_and_constructors/code_constructs/polymorphic_type/polymorphic_type_lib.mli:2: either.Right ./examples/docs/fields_and_constructors/code_constructs/polymorphic_type/polymorphic_type_lib.mli:3: both.left -./examples/docs/limitations/modtype/modtype_with_intf.mli:4: Ftor_with.ctor.Ctor: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:4: Incl.ctor.Ctor: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:4: Incl_with.ctor.Ctor: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:4: With.ctor.Ctor: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:5: Ftor_with.field.field: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:5: Incl.field.field: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:5: Incl_with.field.field: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:5: With.field.field: Should not be detected ./examples/using_dune/preprocessed_lib/preprocessed.mli:14: constructors.Unused ./examples/using_dune/preprocessed_lib/preprocessed.mli:19: constr_with_eq.Unused ./examples/using_dune/preprocessed_lib/preprocessed.mli:23: record.unused @@ -388,14 +350,6 @@ Nothing else to report in this section ============================= ./examples/docs/coding_style/opt/opt.ml:15: ?index -./examples/docs/limitations/modtype/modtype_with_intf.mli:9: ?always: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:18: ?always: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:29: ?always: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:36: ?always: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:9: ?always: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:36: ?always: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:74: ?always: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:108: ?always: Should not be detected ./examples/docs/optional_arguments/code_constructs/external_app/external_app_lib.mli:3: ?max ./examples/docs/optional_arguments/code_constructs/hof/hof_bin.ml:2: ?index @@ -557,14 +511,6 @@ Nothing else to report in this section .> OPTIONAL ARGUMENTS: NEVER: ============================ -./examples/docs/limitations/modtype/modtype_with_intf.mli:9: ?never: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:18: ?never: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:29: ?never: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:36: ?never: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:9: ?never: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:36: ?never: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:74: ?never: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:108: ?never: Should not be detected ./examples/docs/optional_arguments/code_constructs/external_app/external_app_lib.mli:2: ?min ./examples/docs/optional_arguments/code_constructs/internal_app/internal_app_lib.ml:2: ?min @@ -781,7 +727,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 653 +Total: 599 Success: 595 -Failed: 58 -Ratio: 91.1179173047% +Failed: 4 +Ratio: 99.3322203673% diff --git a/check/internal/internal.ref b/check/internal/internal.ref index dad1e95..0459212 100644 --- a/check/internal/internal.ref +++ b/check/internal/internal.ref @@ -23,9 +23,7 @@ ./examples/docs/exported_values/code_constructs/module/module_lib.mli:6: M.unused -./examples/docs/exported_values/limitations/incl_same_name/incl_with_intf/with_intf.mli:2: unused: Should not be detected ./examples/docs/exported_values/limitations/incl_same_name/incl_with_intf/with_intf.mli:4: redefined_unused -./examples/docs/exported_values/limitations/incl_same_name/incl_with_intf/without_intf.ml:2: unused: Should not be detected ./examples/docs/exported_values/limitations/incl_same_name/incl_with_intf/without_intf.mli:4: redefined_unused ./examples/docs/exported_values/limitations/incl_same_name/incl_without_intf/with_intf.ml:4: redefined_unused @@ -135,34 +133,6 @@ Nothing else to report in this section .> UNUSED METHODS: ================= -./examples/docs/limitations/modtype/modtype_with_intf.mli:7: Ftor_with.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:7: Incl.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:7: Incl_with.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:7: With.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:8: Ftor_with.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:8: Incl.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:8: Incl_with.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:8: With.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:18: Subst.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:18: Subst.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:29: Incl_subst.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:29: Incl_subst.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:36: Ftor_subst.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:36: Ftor_subst.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:7: Ftor_with.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:7: Incl.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:7: Incl_with.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:7: With.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:8: Ftor_with.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:8: Incl.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:8: Incl_with.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:8: With.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:36: Subst.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:36: Subst.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:74: Incl_subst.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:74: Incl_subst.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:108: Ftor_subst.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:108: Ftor_subst.o#m: Should not be detected ./examples/docs/methods/code_constructs/class/class_bin.ml:2: unused_class#unused_method ./examples/docs/methods/code_constructs/class/class_lib.mli:2: int_stack#reset @@ -256,14 +226,6 @@ Nothing else to report in this section ./examples/docs/fields_and_constructors/code_constructs/polymorphic_type/polymorphic_type_lib.mli:2: either.Right ./examples/docs/fields_and_constructors/code_constructs/polymorphic_type/polymorphic_type_lib.mli:3: both.left -./examples/docs/limitations/modtype/modtype_with_intf.mli:4: Ftor_with.ctor.Ctor: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:4: Incl.ctor.Ctor: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:4: Incl_with.ctor.Ctor: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:4: With.ctor.Ctor: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:5: Ftor_with.field.field: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:5: Incl.field.field: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:5: Incl_with.field.field: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:5: With.field.field: Should not be detected ./examples/using_dune/preprocessed_lib/preprocessed.mli:14: constructors.Unused ./examples/using_dune/preprocessed_lib/preprocessed.mli:19: constr_with_eq.Unused ./examples/using_dune/preprocessed_lib/preprocessed.mli:23: record.unused @@ -340,14 +302,6 @@ Nothing else to report in this section ============================= ./examples/docs/coding_style/opt/opt.ml:15: ?index -./examples/docs/limitations/modtype/modtype_with_intf.mli:9: ?always: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:18: ?always: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:29: ?always: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:36: ?always: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:9: ?always: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:36: ?always: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:74: ?always: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:108: ?always: Should not be detected ./examples/docs/optional_arguments/code_constructs/external_app/external_app_lib.mli:3: ?max ./examples/docs/optional_arguments/code_constructs/hof/hof_bin.ml:2: ?index @@ -509,14 +463,6 @@ Nothing else to report in this section .> OPTIONAL ARGUMENTS: NEVER: ============================ -./examples/docs/limitations/modtype/modtype_with_intf.mli:9: ?never: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:18: ?never: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:29: ?never: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:36: ?never: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:9: ?never: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:36: ?never: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:74: ?never: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:108: ?never: Should not be detected ./examples/docs/optional_arguments/code_constructs/external_app/external_app_lib.mli:2: ?min ./examples/docs/optional_arguments/code_constructs/internal_app/internal_app_lib.ml:2: ?min @@ -733,7 +679,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 609 +Total: 555 Success: 551 -Failed: 58 -Ratio: 90.4761904762% +Failed: 4 +Ratio: 99.2792792793% diff --git a/check/threshold-1/threshold-1.ref b/check/threshold-1/threshold-1.ref index 65aaef2..0538fc9 100644 --- a/check/threshold-1/threshold-1.ref +++ b/check/threshold-1/threshold-1.ref @@ -23,9 +23,7 @@ ./examples/docs/exported_values/code_constructs/module/module_lib.mli:6: M.unused -./examples/docs/exported_values/limitations/incl_same_name/incl_with_intf/with_intf.mli:2: unused: Should not be detected ./examples/docs/exported_values/limitations/incl_same_name/incl_with_intf/with_intf.mli:4: redefined_unused -./examples/docs/exported_values/limitations/incl_same_name/incl_with_intf/without_intf.ml:2: unused: Should not be detected ./examples/docs/exported_values/limitations/incl_same_name/incl_with_intf/without_intf.mli:4: redefined_unused ./examples/docs/exported_values/limitations/incl_same_name/incl_without_intf/with_intf.ml:4: redefined_unused @@ -169,9 +167,7 @@ ./examples/docs/exported_values/hello_world/hello_world_without_intf.ml:2: hello ./examples/docs/exported_values/hello_world/hello_world_without_intf.ml:3: goodbye -./examples/docs/exported_values/limitations/incl_same_name/incl_with_intf/with_intf.mli:3: used: Should not be detected ./examples/docs/exported_values/limitations/incl_same_name/incl_with_intf/with_intf.mli:5: redefined_used -./examples/docs/exported_values/limitations/incl_same_name/incl_with_intf/without_intf.ml:3: used: Should not be detected ./examples/docs/exported_values/limitations/incl_same_name/incl_with_intf/without_intf.mli:5: redefined_used ./examples/docs/exported_values/limitations/incl_same_name/incl_without_intf/with_intf.ml:5: redefined_used @@ -430,34 +426,6 @@ Nothing else to report in this section .> UNUSED METHODS: ================= -./examples/docs/limitations/modtype/modtype_with_intf.mli:7: Ftor_with.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:7: Incl.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:7: Incl_with.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:7: With.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:8: Ftor_with.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:8: Incl.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:8: Incl_with.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:8: With.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:18: Subst.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:18: Subst.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:29: Incl_subst.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:29: Incl_subst.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:36: Ftor_subst.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:36: Ftor_subst.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:7: Ftor_with.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:7: Incl.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:7: Incl_with.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:7: With.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:8: Ftor_with.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:8: Incl.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:8: Incl_with.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:8: With.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:36: Subst.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:36: Subst.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:74: Incl_subst.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:74: Incl_subst.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:108: Ftor_subst.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:108: Ftor_subst.o#m: Should not be detected ./examples/docs/methods/code_constructs/class/class_bin.ml:2: unused_class#unused_method ./examples/docs/methods/code_constructs/class/class_lib.mli:2: int_stack#reset @@ -603,7 +571,6 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/obj/without_class.mli:28: _self_used_factory#used_fun ./examples/using_dune/wrapped_lib/obj/without_class.mli:28: _self_used_factory#used_int -./examples/using_make/advanced/func.mli:3: M.c#f: Should not be detected ./examples/using_make/advanced/mod.mli:4: p#f ./examples/using_make/obj/class.mli:1: c#f @@ -644,14 +611,6 @@ Nothing else to report in this section ./examples/docs/fields_and_constructors/code_constructs/polymorphic_type/polymorphic_type_lib.mli:2: either.Right ./examples/docs/fields_and_constructors/code_constructs/polymorphic_type/polymorphic_type_lib.mli:3: both.left -./examples/docs/limitations/modtype/modtype_with_intf.mli:4: Ftor_with.ctor.Ctor: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:4: Incl.ctor.Ctor: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:4: Incl_with.ctor.Ctor: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:4: With.ctor.Ctor: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:5: Ftor_with.field.field: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:5: Incl.field.field: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:5: Incl_with.field.field: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:5: With.field.field: Should not be detected ./examples/using_dune/preprocessed_lib/preprocessed.mli:14: constructors.Unused ./examples/using_dune/preprocessed_lib/preprocessed.mli:19: constr_with_eq.Unused ./examples/using_dune/preprocessed_lib/preprocessed.mli:23: record.unused @@ -809,14 +768,6 @@ Nothing else to report in this section ============================= ./examples/docs/coding_style/opt/opt.ml:15: ?index -./examples/docs/limitations/modtype/modtype_with_intf.mli:9: ?always: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:18: ?always: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:29: ?always: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:36: ?always: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:9: ?always: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:36: ?always: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:74: ?always: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:108: ?always: Should not be detected ./examples/docs/optional_arguments/code_constructs/external_app/external_app_lib.mli:3: ?max ./examples/docs/optional_arguments/code_constructs/hof/hof_bin.ml:2: ?index @@ -978,14 +929,6 @@ Nothing else to report in this section .> OPTIONAL ARGUMENTS: NEVER: ============================ -./examples/docs/limitations/modtype/modtype_with_intf.mli:9: ?never: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:18: ?never: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:29: ?never: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:36: ?never: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:9: ?never: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:36: ?never: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:74: ?never: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:108: ?never: Should not be detected ./examples/docs/optional_arguments/code_constructs/external_app/external_app_lib.mli:2: ?min ./examples/docs/optional_arguments/code_constructs/internal_app/internal_app_lib.ml:2: ?min @@ -1202,7 +1145,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 999 +Total: 942 Success: 935 -Failed: 64 -Ratio: 93.5935935936% +Failed: 7 +Ratio: 99.2569002123% diff --git a/check/threshold-3-0.5/threshold-3-0.5.ref b/check/threshold-3-0.5/threshold-3-0.5.ref index 08716e2..e345004 100644 --- a/check/threshold-3-0.5/threshold-3-0.5.ref +++ b/check/threshold-3-0.5/threshold-3-0.5.ref @@ -23,9 +23,7 @@ ./examples/docs/exported_values/code_constructs/module/module_lib.mli:6: M.unused -./examples/docs/exported_values/limitations/incl_same_name/incl_with_intf/with_intf.mli:2: unused: Should not be detected ./examples/docs/exported_values/limitations/incl_same_name/incl_with_intf/with_intf.mli:4: redefined_unused -./examples/docs/exported_values/limitations/incl_same_name/incl_with_intf/without_intf.ml:2: unused: Should not be detected ./examples/docs/exported_values/limitations/incl_same_name/incl_with_intf/without_intf.mli:4: redefined_unused ./examples/docs/exported_values/limitations/incl_same_name/incl_without_intf/with_intf.ml:4: redefined_unused @@ -169,9 +167,7 @@ ./examples/docs/exported_values/hello_world/hello_world_without_intf.ml:2: hello ./examples/docs/exported_values/hello_world/hello_world_without_intf.ml:3: goodbye -./examples/docs/exported_values/limitations/incl_same_name/incl_with_intf/with_intf.mli:3: used: Should not be detected ./examples/docs/exported_values/limitations/incl_same_name/incl_with_intf/with_intf.mli:5: redefined_used -./examples/docs/exported_values/limitations/incl_same_name/incl_with_intf/without_intf.ml:3: used: Should not be detected ./examples/docs/exported_values/limitations/incl_same_name/incl_with_intf/without_intf.mli:5: redefined_used ./examples/docs/exported_values/limitations/incl_same_name/incl_without_intf/with_intf.ml:5: redefined_used @@ -432,10 +428,6 @@ ./examples/docs/exported_values/hello_world/hello_world_with_intf.mli:4: world ./examples/docs/exported_values/hello_world/hello_world_without_intf.ml:4: world -./examples/docs/limitations/modtype/modtype_with_intf.mli:29: Incl_subst.always: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:29: Incl_subst.f: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:29: Incl_subst.o: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:29: Incl_subst.x: Should not be detected ./examples/docs/methods/limitations/alias/alias_lib.mli:2: original ./examples/docs/optional_arguments/code_constructs/intext_app/intext_app_lib.mli:2: max @@ -577,34 +569,6 @@ Nothing else to report in this section .> UNUSED METHODS: ================= -./examples/docs/limitations/modtype/modtype_with_intf.mli:7: Ftor_with.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:7: Incl.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:7: Incl_with.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:7: With.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:8: Ftor_with.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:8: Incl.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:8: Incl_with.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:8: With.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:18: Subst.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:18: Subst.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:29: Incl_subst.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:29: Incl_subst.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:36: Ftor_subst.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:36: Ftor_subst.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:7: Ftor_with.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:7: Incl.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:7: Incl_with.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:7: With.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:8: Ftor_with.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:8: Incl.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:8: Incl_with.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:8: With.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:36: Subst.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:36: Subst.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:74: Incl_subst.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:74: Incl_subst.o#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:108: Ftor_subst.c#m: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:108: Ftor_subst.o#m: Should not be detected ./examples/docs/methods/code_constructs/class/class_bin.ml:2: unused_class#unused_method ./examples/docs/methods/code_constructs/class/class_lib.mli:2: int_stack#reset @@ -750,7 +714,6 @@ Nothing else to report in this section ./examples/using_dune/wrapped_lib/obj/without_class.mli:28: _self_used_factory#used_fun ./examples/using_dune/wrapped_lib/obj/without_class.mli:28: _self_used_factory#used_int -./examples/using_make/advanced/func.mli:3: M.c#f: Should not be detected ./examples/using_make/advanced/mod.mli:4: p#f ./examples/using_make/obj/class.mli:1: c#f @@ -830,14 +793,6 @@ Nothing else to report in this section ./examples/docs/fields_and_constructors/code_constructs/polymorphic_type/polymorphic_type_lib.mli:2: either.Right ./examples/docs/fields_and_constructors/code_constructs/polymorphic_type/polymorphic_type_lib.mli:3: both.left -./examples/docs/limitations/modtype/modtype_with_intf.mli:4: Ftor_with.ctor.Ctor: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:4: Incl.ctor.Ctor: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:4: Incl_with.ctor.Ctor: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:4: With.ctor.Ctor: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:5: Ftor_with.field.field: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:5: Incl.field.field: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:5: Incl_with.field.field: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:5: With.field.field: Should not be detected ./examples/using_dune/preprocessed_lib/preprocessed.mli:14: constructors.Unused ./examples/using_dune/preprocessed_lib/preprocessed.mli:19: constr_with_eq.Unused ./examples/using_dune/preprocessed_lib/preprocessed.mli:23: record.unused @@ -991,12 +946,6 @@ Nothing else to report in this section .>-> ALMOST UNUSED CONSTRUCTORS/RECORD FIELDS: Called 2 time(s): ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -./examples/docs/limitations/modtype/modtype_with_intf.mli:18: Subst.ctor.Ctor: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:18: Subst.field.field: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:29: Incl_subst.ctor.Ctor: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:29: Incl_subst.field.field: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:36: Ftor_subst.ctor.Ctor: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:36: Ftor_subst.field.field: Should not be detected ./examples/using_dune/preprocessed_lib/preprocessed.mli:15: constructors.Used ./examples/using_dune/preprocessed_lib/preprocessed.mli:24: record.used ./examples/using_dune/preprocessed_lib/preprocessed_no_intf.ml:26: constructors.Used @@ -1044,14 +993,6 @@ Nothing else to report in this section ============================= ./examples/docs/coding_style/opt/opt.ml:15: ?index -./examples/docs/limitations/modtype/modtype_with_intf.mli:9: ?always: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:18: ?always: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:29: ?always: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:36: ?always: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:9: ?always: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:36: ?always: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:74: ?always: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:108: ?always: Should not be detected ./examples/docs/optional_arguments/code_constructs/external_app/external_app_lib.mli:3: ?max ./examples/docs/optional_arguments/code_constructs/hof/hof_bin.ml:2: ?index @@ -1310,14 +1251,6 @@ Nothing else to report in this section .> OPTIONAL ARGUMENTS: NEVER: ============================ -./examples/docs/limitations/modtype/modtype_with_intf.mli:9: ?never: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:18: ?never: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:29: ?never: Should not be detected -./examples/docs/limitations/modtype/modtype_with_intf.mli:36: ?never: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:9: ?never: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:36: ?never: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:74: ?never: Should not be detected -./examples/docs/limitations/modtype/modtype_without_intf.ml:108: ?never: Should not be detected ./examples/docs/optional_arguments/code_constructs/external_app/external_app_lib.mli:2: ?min ./examples/docs/optional_arguments/code_constructs/internal_app/internal_app_lib.ml:2: ?min @@ -1616,7 +1549,7 @@ Nothing else to report in this section -------------------------------------------------------------------------------- -Total: 1331 +Total: 1264 Success: 1257 -Failed: 74 -Ratio: 94.4402704733% +Failed: 7 +Ratio: 99.4462025316% diff --git a/docs/LIMITATIONS.md b/docs/LIMITATIONS.md index 30c78de..f23703d 100644 --- a/docs/LIMITATIONS.md +++ b/docs/LIMITATIONS.md @@ -1,7 +1,7 @@ # Table of contents + [Module type](#module-type) -+ [Module type with and inclusion](#module-type-with-and-inclusion) ++ [Module type of](#module-type-of) The limitations listed below apply to all the reportable elements of code. Coding style issues are not concerned unless specified otherwise. @@ -22,279 +22,15 @@ A future improvement would be to report unused elements declared in module types by considering all the elemnts defined in modules of such types as instances of the elements in the module types. -# Module type with and inclusion - -Related issue : -[issue #64](https://github.com/LexiFi/dead_code_analyzer/issues/64). - -According to the above limitation on elements in module types, elements included -from a module type (`include T`) should not be reported. Even more so according -to the semantics described in the -[exported values' Include](./exported_values/code_constructs/INCLUDE.md) -example. -Similarly, elements defined in a module type with constraints (`T with ...`) -should not be reported. - -This is mostly the case for unused exported values, unless there is a substition -(`T with ... := ...`) and not .mli is provided, or a .mli is provided and the 2 -contructs are mixed into an included module type with substitution -(`include T with ... := ...`). -This is however, not the case at all for constructors, fields, and methods. -Optional arguments always/never used are only affected by substitutions. - -## Example - -The reference files for this example are in the +Examples of this limitation are avaialble in the [modtype](../../examples/docs/limitations/modtype) directory. -The reference takes place in `/tmp/docs/limitations`, which -is a copy of the [limitations](../../examples/docs/limitations) directory. -Reported locations may differ depending on the location of the source files. - -The compilation command is : -``` -make -C modtype build -``` - -The analysis command is : -``` -make -C modtype analyze -``` - -The compile + analyze command is : -``` -make -C modtype -``` - -Code: -```OCaml -(* modtype_with_intf.mli *) -module type T = sig - type t - type ctor = Ctor - type field = {field : unit} - val x : t - val o : < m : t > - class c : object method m : t end - val f : ?always:t -> ?never:t -> unit -> t - (* to use as [always] in call to [f] *) - val always : t -end - -module Regular : T - -module With : T with type t = int - -module Subst : T with type t := int - -module Incl : sig - include T -end - -module Incl_with : sig - include T with type t = int -end - -module Incl_subst : sig - include T with type t := int -end - -module Ftor () : T - -module Ftor_with () : T with type t = int - -module Ftor_subst () : T with type t := int -``` -The other files are not displayed here. -`modtype_without_intf` is equivalent to `modtype_with_intf`'s interface and -implementation merged together. `modtype_bin` uses the function's `f` to track -its optional parameters. -The modules are all defined as: -```OCaml -struct - type t = int - type ctor = Ctor - type field = {field : unit} - let x = 0 - let o = object method m = 0 end - class c = object method m = 0 end - let f ?always:_ ?never:_ () = 0 - let always = 0 -end -``` - -Compile and analyze: -``` -$ make -C modtype -make: Entering directory '/tmp/docs/limitations/modtype' -ocamlopt -bin-annot modtype_with_intf.mli modtype_with_intf.ml modtype_without_intf.ml modtype_bin.ml -dead_code_analyzer --all -E threshold:4 -M threshold:4 -T threshold:4 . -Scanning files... - [DONE] - -.> UNUSED EXPORTED VALUES: -========================= - - -.>-> ALMOST UNUSED EXPORTED VALUES: Called 2 time(s): -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -/tmp/docs/limitations/modtype/modtype_with_intf.mli:29: Incl_subst.always -/tmp/docs/limitations/modtype/modtype_with_intf.mli:29: Incl_subst.f -/tmp/docs/limitations/modtype/modtype_with_intf.mli:29: Incl_subst.o -/tmp/docs/limitations/modtype/modtype_with_intf.mli:29: Incl_subst.x --------- - - -.>-> ALMOST UNUSED EXPORTED VALUES: Called 4 time(s): -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -/tmp/docs/limitations/modtype/modtype_without_intf.ml:36: Subst.always -/tmp/docs/limitations/modtype/modtype_without_intf.ml:36: Subst.f -/tmp/docs/limitations/modtype/modtype_without_intf.ml:36: Subst.o -/tmp/docs/limitations/modtype/modtype_without_intf.ml:36: Subst.x -/tmp/docs/limitations/modtype/modtype_without_intf.ml:74: Incl_subst.always -/tmp/docs/limitations/modtype/modtype_without_intf.ml:74: Incl_subst.f -/tmp/docs/limitations/modtype/modtype_without_intf.ml:74: Incl_subst.o -/tmp/docs/limitations/modtype/modtype_without_intf.ml:74: Incl_subst.x -/tmp/docs/limitations/modtype/modtype_without_intf.ml:108: Ftor_subst.always -/tmp/docs/limitations/modtype/modtype_without_intf.ml:108: Ftor_subst.f -/tmp/docs/limitations/modtype/modtype_without_intf.ml:108: Ftor_subst.o -/tmp/docs/limitations/modtype/modtype_without_intf.ml:108: Ftor_subst.x - -Nothing else to report in this section --------------------------------------------------------------------------------- - - -.> UNUSED METHODS: -================= -/tmp/docs/limitations/modtype/modtype_with_intf.mli:7: Ftor_with.o#m -/tmp/docs/limitations/modtype/modtype_with_intf.mli:7: Incl.o#m -/tmp/docs/limitations/modtype/modtype_with_intf.mli:7: Incl_with.o#m -/tmp/docs/limitations/modtype/modtype_with_intf.mli:7: With.o#m -/tmp/docs/limitations/modtype/modtype_with_intf.mli:8: Ftor_with.c#m -/tmp/docs/limitations/modtype/modtype_with_intf.mli:8: Incl.c#m -/tmp/docs/limitations/modtype/modtype_with_intf.mli:8: Incl_with.c#m -/tmp/docs/limitations/modtype/modtype_with_intf.mli:8: With.c#m -/tmp/docs/limitations/modtype/modtype_with_intf.mli:18: Subst.c#m -/tmp/docs/limitations/modtype/modtype_with_intf.mli:18: Subst.o#m -/tmp/docs/limitations/modtype/modtype_with_intf.mli:29: Incl_subst.c#m -/tmp/docs/limitations/modtype/modtype_with_intf.mli:29: Incl_subst.o#m -/tmp/docs/limitations/modtype/modtype_with_intf.mli:36: Ftor_subst.c#m -/tmp/docs/limitations/modtype/modtype_with_intf.mli:36: Ftor_subst.o#m -/tmp/docs/limitations/modtype/modtype_without_intf.ml:7: Ftor_with.o#m -/tmp/docs/limitations/modtype/modtype_without_intf.ml:7: Incl.o#m -/tmp/docs/limitations/modtype/modtype_without_intf.ml:7: Incl_with.o#m -/tmp/docs/limitations/modtype/modtype_without_intf.ml:7: With.o#m -/tmp/docs/limitations/modtype/modtype_without_intf.ml:8: Ftor_with.c#m -/tmp/docs/limitations/modtype/modtype_without_intf.ml:8: Incl.c#m -/tmp/docs/limitations/modtype/modtype_without_intf.ml:8: Incl_with.c#m -/tmp/docs/limitations/modtype/modtype_without_intf.ml:8: With.c#m -/tmp/docs/limitations/modtype/modtype_without_intf.ml:36: Subst.c#m -/tmp/docs/limitations/modtype/modtype_without_intf.ml:36: Subst.o#m -/tmp/docs/limitations/modtype/modtype_without_intf.ml:74: Incl_subst.c#m -/tmp/docs/limitations/modtype/modtype_without_intf.ml:74: Incl_subst.o#m -/tmp/docs/limitations/modtype/modtype_without_intf.ml:108: Ftor_subst.c#m -/tmp/docs/limitations/modtype/modtype_without_intf.ml:108: Ftor_subst.o#m --------- - - - -Nothing else to report in this section --------------------------------------------------------------------------------- - - -.> UNUSED CONSTRUCTORS/RECORD FIELDS: -==================================== -/tmp/docs/limitations/modtype/modtype_with_intf.mli:4: Ftor_with.ctor.Ctor -/tmp/docs/limitations/modtype/modtype_with_intf.mli:4: Incl.ctor.Ctor -/tmp/docs/limitations/modtype/modtype_with_intf.mli:4: Incl_with.ctor.Ctor -/tmp/docs/limitations/modtype/modtype_with_intf.mli:4: With.ctor.Ctor -/tmp/docs/limitations/modtype/modtype_with_intf.mli:5: Ftor_with.field.field -/tmp/docs/limitations/modtype/modtype_with_intf.mli:5: Incl.field.field -/tmp/docs/limitations/modtype/modtype_with_intf.mli:5: Incl_with.field.field -/tmp/docs/limitations/modtype/modtype_with_intf.mli:5: With.field.field --------- - - -.>-> ALMOST UNUSED CONSTRUCTORS/RECORD FIELDS: Called 2 time(s): -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -/tmp/docs/limitations/modtype/modtype_with_intf.mli:18: Subst.ctor.Ctor -/tmp/docs/limitations/modtype/modtype_with_intf.mli:18: Subst.field.field -/tmp/docs/limitations/modtype/modtype_with_intf.mli:29: Incl_subst.ctor.Ctor -/tmp/docs/limitations/modtype/modtype_with_intf.mli:29: Incl_subst.field.field -/tmp/docs/limitations/modtype/modtype_with_intf.mli:36: Ftor_subst.ctor.Ctor -/tmp/docs/limitations/modtype/modtype_with_intf.mli:36: Ftor_subst.field.field --------- - - -.>-> ALMOST UNUSED CONSTRUCTORS/RECORD FIELDS: Called 4 time(s): -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -/tmp/docs/limitations/modtype/modtype_without_intf.ml:4: Ftor_with.ctor.Ctor -/tmp/docs/limitations/modtype/modtype_without_intf.ml:4: Incl.ctor.Ctor -/tmp/docs/limitations/modtype/modtype_without_intf.ml:4: Incl_with.ctor.Ctor -/tmp/docs/limitations/modtype/modtype_without_intf.ml:4: With.ctor.Ctor -/tmp/docs/limitations/modtype/modtype_without_intf.ml:5: Ftor_with.field.field -/tmp/docs/limitations/modtype/modtype_without_intf.ml:5: Incl.field.field -/tmp/docs/limitations/modtype/modtype_without_intf.ml:5: Incl_with.field.field -/tmp/docs/limitations/modtype/modtype_without_intf.ml:5: With.field.field -/tmp/docs/limitations/modtype/modtype_without_intf.ml:36: Subst.ctor.Ctor -/tmp/docs/limitations/modtype/modtype_without_intf.ml:36: Subst.field.field -/tmp/docs/limitations/modtype/modtype_without_intf.ml:74: Incl_subst.ctor.Ctor -/tmp/docs/limitations/modtype/modtype_without_intf.ml:74: Incl_subst.field.field -/tmp/docs/limitations/modtype/modtype_without_intf.ml:108: Ftor_subst.ctor.Ctor -/tmp/docs/limitations/modtype/modtype_without_intf.ml:108: Ftor_subst.field.field - -Nothing else to report in this section --------------------------------------------------------------------------------- --------------------------------------------------------------------------------- - - -.> OPTIONAL ARGUMENTS: ALWAYS: -============================= -/tmp/docs/limitations/modtype/modtype_with_intf.mli:9: ?always -/tmp/docs/limitations/modtype/modtype_with_intf.mli:18: ?always -/tmp/docs/limitations/modtype/modtype_with_intf.mli:29: ?always -/tmp/docs/limitations/modtype/modtype_with_intf.mli:36: ?always -/tmp/docs/limitations/modtype/modtype_without_intf.ml:9: ?always -/tmp/docs/limitations/modtype/modtype_without_intf.ml:36: ?always -/tmp/docs/limitations/modtype/modtype_without_intf.ml:74: ?always -/tmp/docs/limitations/modtype/modtype_without_intf.ml:108: ?always - -Nothing else to report in this section --------------------------------------------------------------------------------- - - -.> OPTIONAL ARGUMENTS: NEVER: -============================ -/tmp/docs/limitations/modtype/modtype_with_intf.mli:9: ?never -/tmp/docs/limitations/modtype/modtype_with_intf.mli:18: ?never -/tmp/docs/limitations/modtype/modtype_with_intf.mli:29: ?never -/tmp/docs/limitations/modtype/modtype_with_intf.mli:36: ?never -/tmp/docs/limitations/modtype/modtype_without_intf.ml:9: ?never -/tmp/docs/limitations/modtype/modtype_without_intf.ml:36: ?never -/tmp/docs/limitations/modtype/modtype_without_intf.ml:74: ?never -/tmp/docs/limitations/modtype/modtype_without_intf.ml:108: ?never - -Nothing else to report in this section --------------------------------------------------------------------------------- - - -.> CODING STYLE: -=============== - -Nothing else to report in this section --------------------------------------------------------------------------------- - +# Module type of -make: Leaving directory '/tmp/docs/limitations/modtype' -``` -> [!NOTE] -> The analyzer is run with thresholds. Because elements of `T` share the same -> location at the point of use of `T`, the analyzer gets confused and considers -> some unused elements as used. Using thresholds enables reporting elements used -> up to a fixed amount. -> For more details about the command line arguments see [the more general Usage -documentation](../USAGE.md). +The same restricition as for the [Module type](#module-type) limitation above +is applied to modules whose module types are recovered via `module type of`. +Using this construction makes the module behave similarly to a module type, so +the module type semantics apply to it. -The analyzer reports elements although they are all defined within module type -`T`. -Following its semantics on module types, the report should be empty. +Examples of this limitation are avaialble in the +[modtype_of](../../examples/docs/limitations/modtype_of) directory. diff --git a/examples/docs/limitations/Makefile b/examples/docs/limitations/Makefile index b14152c..ebf9a1a 100644 --- a/examples/docs/limitations/Makefile +++ b/examples/docs/limitations/Makefile @@ -4,7 +4,9 @@ all: build build: make -C modtype build + make -C modtype_of build clean: rm -f *~ *.cm* *.o *.obj make -C modtype clean + make -C modtype_of clean diff --git a/examples/docs/limitations/modtype/modtype_bin.ml b/examples/docs/limitations/modtype/modtype_bin.ml index 9759f41..efd5019 100644 --- a/examples/docs/limitations/modtype/modtype_bin.ml +++ b/examples/docs/limitations/modtype/modtype_bin.ml @@ -1,3 +1,4 @@ +(* modtype_bin.ml *) module M_intf = Modtype_with_intf.Ftor () module M_intf_with = Modtype_with_intf.Ftor_with () module M_intf_subst = Modtype_with_intf.Ftor_subst () diff --git a/examples/docs/limitations/modtype/modtype_with_intf.ml b/examples/docs/limitations/modtype/modtype_with_intf.ml index 364caf7..30bc351 100644 --- a/examples/docs/limitations/modtype/modtype_with_intf.ml +++ b/examples/docs/limitations/modtype/modtype_with_intf.ml @@ -1,4 +1,4 @@ -(* modtype_with_intf.mli *) +(* modtype_with_intf.ml *) module type T = sig type t type ctor = Ctor diff --git a/examples/docs/limitations/modtype_of/Makefile b/examples/docs/limitations/modtype_of/Makefile new file mode 100644 index 0000000..ebadc2e --- /dev/null +++ b/examples/docs/limitations/modtype_of/Makefile @@ -0,0 +1,12 @@ +SRC:=modtype_of_with_intf.mli modtype_of_with_intf.ml modtype_of_without_intf.ml modtype_of_bin.ml + +all: build analyze + +build: + ocamlopt -bin-annot ${SRC} + +analyze: + dead_code_analyzer --all -E threshold:4 -M threshold:4 -T threshold:4 . + +clean: + rm -f *.cm* *.o a.out diff --git a/examples/docs/limitations/modtype_of/modtype_of_bin.ml b/examples/docs/limitations/modtype_of/modtype_of_bin.ml new file mode 100644 index 0000000..e983843 --- /dev/null +++ b/examples/docs/limitations/modtype_of/modtype_of_bin.ml @@ -0,0 +1,30 @@ +(* modtype_of_bin.ml *) +module M_intf = Modtype_of_with_intf.Ftor () +module M_intf_with = Modtype_of_with_intf.Ftor_with () +module M_intf_subst = Modtype_of_with_intf.Ftor_subst () + +let () = + let open Modtype_of_with_intf in + With.(f ~always ()) |> ignore; + Subst.(f ~always ()) |> ignore; + Incl.(f ~always ()) |> ignore; + Incl_with.(f ~always ()) |> ignore; + Incl_subst.f ~always:Incl_subst.always () |> ignore; + M_intf.(f ~always ()) |> ignore; + M_intf_with.(f ~always ()) |> ignore; + M_intf_subst.(f ~always ()) |> ignore + +module M_no_intf = Modtype_of_without_intf.Ftor () +module M_no_intf_with = Modtype_of_without_intf.Ftor_with () +module M_no_intf_subst = Modtype_of_without_intf.Ftor_subst () + +let () = + let open Modtype_of_without_intf in + With.(f ~always ()) |> ignore; + Subst.(f ~always ()) |> ignore; + Incl.(f ~always ()) |> ignore; + Incl_with.(f ~always ()) |> ignore; + Incl_subst.f ~always:Incl_subst.always () |> ignore; + M_no_intf.(f ~always ()) |> ignore; + M_no_intf_with.(f ~always ()) |> ignore; + M_no_intf_subst.(f ~always ()) |> ignore diff --git a/examples/docs/limitations/modtype_of/modtype_of_with_intf.ml b/examples/docs/limitations/modtype_of/modtype_of_with_intf.ml new file mode 100644 index 0000000..3531c4e --- /dev/null +++ b/examples/docs/limitations/modtype_of/modtype_of_with_intf.ml @@ -0,0 +1,111 @@ +(* modtype_of_with_intf.ml *) +module M = struct + type t = int + type ctor = Ctor + type field = {field : unit} + let x = 0 + let o = object method m = 0 end + class c = object method m = 0 end + let f ?always:_ ?never:_ () = 0 + (* to use as [always] in call to [f] *) + let always = 0 +end + +module Regular = struct + type t = int + type ctor = Ctor + type field = {field : unit} + let x = 0 + let o = object method m = 0 end + class c = object method m = 0 end + let f ?always:_ ?never:_ () = 0 + let always = 0 +end + +module With = struct + type t = int + type ctor = Ctor + type field = {field : unit} + let x = 0 + let o = object method m = 0 end + class c = object method m = 0 end + let f ?always:_ ?never:_ () = 0 + let always = 0 +end + +module Subst = struct + type t = int + type ctor = Ctor + type field = {field : unit} + let x = 0 + let o = object method m = 0 end + class c = object method m = 0 end + let f ?always:_ ?never:_ () = 0 + let always = 0 +end + +module Incl = struct + type t = int + type ctor = Ctor + type field = {field : unit} + let x = 0 + let o = object method m = 0 end + class c = object method m = 0 end + let f ?always:_ ?never:_ () = 0 + let always = 0 +end + +module Incl_with = struct + type t = int + type ctor = Ctor + type field = {field : unit} + let x = 0 + let o = object method m = 0 end + class c = object method m = 0 end + let f ?always:_ ?never:_ () = 0 + let always = 0 +end + +module Incl_subst = struct + type t = int + type ctor = Ctor + type field = {field : unit} + let x = 0 + let o = object method m = 0 end + class c = object method m = 0 end + let f ?always:_ ?never:_ () = 0 + let always = 0 +end + +module Ftor() = struct + type t = int + type ctor = Ctor + type field = {field : unit} + let x = 0 + let o = object method m = 0 end + class c = object method m = 0 end + let f ?always:_ ?never:_ () = 0 + let always = 0 +end + +module Ftor_with() = struct + type t = int + type ctor = Ctor + type field = {field : unit} + let x = 0 + let o = object method m = 0 end + class c = object method m = 0 end + let f ?always:_ ?never:_ () = 0 + let always = 0 +end + +module Ftor_subst() = struct + type t = int + type ctor = Ctor + type field = {field : unit} + let x = 0 + let o = object method m = 0 end + class c = object method m = 0 end + let f ?always:_ ?never:_ () = 0 + let always = 0 +end diff --git a/examples/docs/limitations/modtype_of/modtype_of_with_intf.mli b/examples/docs/limitations/modtype_of/modtype_of_with_intf.mli new file mode 100644 index 0000000..abc9e00 --- /dev/null +++ b/examples/docs/limitations/modtype_of/modtype_of_with_intf.mli @@ -0,0 +1,36 @@ +(* modtype_of_with_intf.mli *) +module M : sig + type t + type ctor = Ctor + type field = {field : unit} + val x : t + val o : < m : t > + class c : object method m : t end + val f : ?always:t -> ?never:t -> unit -> t + (* to use as [always] in call to [f] *) + val always : t +end + +module Regular : module type of M + +module With : module type of M with type t = int + +module Subst : module type of M with type t := int + +module Incl : sig + include module type of M +end + +module Incl_with : sig + include module type of M with type t = int +end + +module Incl_subst : sig + include module type of M with type t := int +end + +module Ftor () : module type of M + +module Ftor_with () : module type of M with type t = int + +module Ftor_subst () : module type of M with type t := int diff --git a/examples/docs/limitations/modtype_of/modtype_of_without_intf.ml b/examples/docs/limitations/modtype_of/modtype_of_without_intf.ml new file mode 100644 index 0000000..be80fc9 --- /dev/null +++ b/examples/docs/limitations/modtype_of/modtype_of_without_intf.ml @@ -0,0 +1,117 @@ +(* modtype_of_without_intf.ml *) +module M = struct + type t = int + type ctor = Ctor + type field = {field : unit} + let x = 0 + let o = object method m = 0 end + class c = object method m = 0 end + let f ?always:_ ?never:_ () = 0 + (* to use as [always] in call to [f] *) + let always = 0 +end + +module Regular : module type of M = struct + type t = int + type ctor = Ctor + type field = {field : unit} + let x = 0 + let o = object method m = 0 end + class c = object method m = 0 end + let f ?always:_ ?never:_ () = 0 + let always = 0 +end + +module With : module type of M with type t = int = struct + type t = int + type ctor = Ctor + type field = {field : unit} + let x = 0 + let o = object method m = 0 end + class c = object method m = 0 end + let f ?always:_ ?never:_ () = 0 + let always = 0 +end + +module Subst : module type of M with type t := int = struct + type t = int + type ctor = Ctor + type field = {field : unit} + let x = 0 + let o = object method m = 0 end + class c = object method m = 0 end + let f ?always:_ ?never:_ () = 0 + let always = 0 +end + +module Incl : sig + include module type of M +end = struct + type t = int + type ctor = Ctor + type field = {field : unit} + let x = 0 + let o = object method m = 0 end + class c = object method m = 0 end + let f ?always:_ ?never:_ () = 0 + let always = 0 +end + +module Incl_with : sig + include module type of M with type t = int +end = struct + type t = int + type ctor = Ctor + type field = {field : unit} + let x = 0 + let o = object method m = 0 end + class c = object method m = 0 end + let f ?always:_ ?never:_ () = 0 + let always = 0 +end + +module Incl_subst : sig + include module type of M with type t := int +end = struct + type t = int + type ctor = Ctor + type field = {field : unit} + let x = 0 + let o = object method m = 0 end + class c = object method m = 0 end + let f ?always:_ ?never:_ () = 0 + let always = 0 +end + +module Ftor() : module type of M = struct + type t = int + type ctor = Ctor + type field = {field : unit} + let x = 0 + let o = object method m = 0 end + class c = object method m = 0 end + let f ?always:_ ?never:_ () = 0 + let always = 0 +end + +module Ftor_with() : module type of M with type t = int = struct + type t = int + type ctor = Ctor + type field = {field : unit} + let x = 0 + let o = object method m = 0 end + class c = object method m = 0 end + let f ?always:_ ?never:_ () = 0 + let always = 0 +end + +module Ftor_subst() : module type of M with type t := int = struct + type t = int + type ctor = Ctor + type field = {field : unit} + let x = 0 + let o = object method m = 0 end + class c = object method m = 0 end + let f ?always:_ ?never:_ () = 0 + let always = 0 +end diff --git a/src/deadCode.ml b/src/deadCode.ml index bdcd53a..3306fd1 100644 --- a/src/deadCode.ml +++ b/src/deadCode.ml @@ -31,78 +31,6 @@ let main_files = Hashtbl.create 256 (* names -> paths *) (******** PROCESSING ********) -type context = - | Toplevel - | In_module of (Ident.t * Location.t) - | In_modtyp of (Ident.t * Location.t) - | Include - -let should_export_value ~context stock loc = - let state = State.get_current () in - let belongs_to_context loc = - match context with - | Toplevel | Include -> true - | In_module (_, md_loc) - | In_modtyp (_, md_loc) -> - (* When a value is part of a module sig because of: - - an include, then its location precedes that of the current module; - - a module type with substitution, then its location ends - with the current module's sig. - Checking that the value's location is striclty within the - module's rules out these 2 cases. - *) - let get_pos_info loc = - let fname, start_l, start_c = - Location.get_pos_info loc.Location.loc_start - in - let _, end_l, end_c = Location.get_pos_info loc.loc_end in - fname, (start_l, start_c), (end_l, end_c) - in - let v_fname, v_start, v_end = get_pos_info loc in - let md_fname, md_start, md_end = get_pos_info md_loc in - let ( > ) (l1, c1) (l2, c2) = - l1 > l2 || (l1 = l2 && c1 > c2) - in - String.equal v_fname md_fname - && v_start > md_start - && md_end > v_end - in - Config.must_report_section state.config.sections.exported_values - && (* do not add the loc in decs if it belongs to a module type - or if it is not actually declared in the current context *) - ( stock != decs - || (not (Hashtbl.mem in_modtype loc.Location.loc_start) - && belongs_to_context loc) - ) - -let rec collect_export ~context path u stock = function - - | Sig_value (id, ({Types.val_loc; val_type; _} as value), _) - when not val_loc.Location.loc_ghost -> - if should_export_value ~context stock val_loc then export path u stock id val_loc; - let path = Ident.create_persistent (Ident.name id ^ "*") :: path in - DeadObj.collect_export path u stock ~obj:val_type val_loc; - !DeadLexiFi.sig_value value - - | Sig_type (id, t, _, _) when stock == decs -> - DeadType.collect_export (id :: path) u stock t - - | Sig_class (id, {Types.cty_type = t; cty_loc = loc; _}, _, _) -> - DeadObj.collect_export (id :: path) u stock ~cltyp:t loc - - | (Sig_module (id, _, {Types.md_type = t; md_loc = loc; _}, _, _) - | Sig_modtype (id, {Types.mtd_type = Some t; mtd_loc = loc; _}, _)) as s -> - let stock, context = - match s, context with - | _, Include -> stock, Include - | Sig_modtype _, _ -> in_modtype, In_modtyp (id, loc) - | _, _ -> stock, In_module (id, loc) - in - Utils.signature_of_modtype t - |> List.iter (collect_export ~context (id :: path) u stock) - - | _ -> () - let rec treat_exp exp args = match exp.exp_desc with @@ -188,8 +116,12 @@ let structure_item super self i = State.File_infos.get_modname state.file_infos |> Ident.create_persistent in + let context = DeadSign.Include in + let path = [module_id] in + let comp_unit = _include in + let stock = incl in List.iter - (collect_export ~context:Include [module_id] _include incl) + (DeadSign.collect_export ~context ~path ~comp_unit ~stock) signature; last_loc := prev_last_loc; in @@ -359,6 +291,11 @@ let collect_references = (* Tast_mapper *) (fun self x -> DeadMod.expr x; super.Tast_mapper.module_expr self x) (fun x -> x.mod_loc) in + let module_type = + wrap + (fun self x -> DeadMod.type_ x; super.Tast_mapper.module_type self x) + (fun x -> x.mty_loc) + in let class_structure = (fun self x -> DeadObj.class_structure x; super.Tast_mapper.class_structure self x) @@ -378,9 +315,11 @@ let collect_references = (* Tast_mapper *) super.Tast_mapper.type_declaration self x in Tast_mapper.{ super with - structure_item; expr; pat; value_binding; - module_expr; class_structure; class_field; typ; - type_declaration + structure_item; + expr; pat; value_binding; + module_expr; module_type; + class_structure; class_field; + typ; type_declaration } @@ -391,10 +330,10 @@ let regabs state = hashtbl_add_unique_to_list main_files (Utils.Filepath.unit fn) () -let read_interface fn signature state = +let read_interface fn (cm_sign : State.File_infos.signature) state = regabs state; if Config.must_report_main state.config then - let u = + let comp_unit = if State.File_infos.has_sourcepath state.file_infos then State.File_infos.get_sourceunit state.file_infos else @@ -404,10 +343,18 @@ let read_interface fn signature state = State.File_infos.get_modname state.file_infos |> Ident.create_persistent in - let f = - collect_export ~context:Toplevel [module_id] u decs - in - List.iter f signature; + let context = DeadSign.Toplevel in + let path = [module_id] in + let stock = decs in + begin match cm_sign with + | Cmi_sign signature -> + let f = + DeadSign.collect_export ~context ~path ~comp_unit ~stock + in + List.iter f signature + | Cmti_sign signature -> + DeadSign.collect_export_from_typedtree ~path ~comp_unit signature + end; last_loc := Lexing.dummy_pos @@ -493,10 +440,10 @@ let load_file fn state = if state.State.config.verbose then Printf.eprintf "Scanning interface from %s\n%!" fn; init_and_continue state fn (fun state -> - match state.file_infos.cmi_sign with + match state.file_infos.cm_sign with | None -> report_error (fn ^ ": missing cmi_sign") - | Some cmi_sign -> - read_interface fn cmi_sign state + | Some cm_sign -> + read_interface fn cm_sign state ) in let process_implementation fn = @@ -554,7 +501,11 @@ let load_file fn state = (* Prepare the list of opt_args for report *) let analyze_opt_args () = DeadArg.eocb (); - let dec_loc loc = Hashtbl.mem main_files (Utils.Filepath.unit loc.Lexing.pos_fname) in + let dec_loc loc = + (* Is the location among the analyzed code and not part of a module type *) + Hashtbl.mem main_files (Utils.Filepath.unit loc.Lexing.pos_fname) + && not (Hashtbl.mem DeadCommon.implicit_decs loc) + in let all = ref [] in let opt_args_tbl = Hashtbl.create 256 in diff --git a/src/deadCommon.ml b/src/deadCommon.ml index 93f915a..7a34189 100644 --- a/src/deadCommon.ml +++ b/src/deadCommon.ml @@ -39,8 +39,8 @@ let abspath : (string, string) Hashtbl.t = Hashtbl.create 256 (* all exported value declarations *) let decs : (Lexing.position, string * string) Hashtbl.t = Hashtbl.create 256 -(* all exported value declarations found in module types *) -let in_modtype : (Lexing.position, string * string) Hashtbl.t = Hashtbl.create 256 +(* all value declarations re-exported by module types uses *) +let implicit_decs : (Lexing.position, unit) Hashtbl.t = Hashtbl.create 256 (* all exported value declarations *) let incl : (Lexing.position, string * string) Hashtbl.t = Hashtbl.create 256 @@ -400,6 +400,18 @@ let export ?(sep = ".") path u stock id loc = let builddir = State.File_infos.get_builddir state.file_infos in hashtbl_add_to_list stock loc.Location.loc_start (builddir, value) +let unexport stock loc = + let state = State.get_current () in + (* The builddir works as a second key to ensure we are not removing + the location of another compilation unit. + *) + let builddir = State.File_infos.get_builddir state.file_infos in + let different_builddir (b, _v) = + not (String.equal b builddir) + in + hashtbl_find_list stock loc.Location.loc_start + |> List.filter different_builddir + |> hashtbl_replace_list stock loc.Location.loc_start (**** REPORTING ****) diff --git a/src/deadMod.ml b/src/deadMod.ml index 6d0fd9a..d5d4fd0 100644 --- a/src/deadMod.ml +++ b/src/deadMod.ml @@ -76,6 +76,13 @@ let expr m = match m.mod_desc with | _ -> () +let type_ mt = + let on_mismatch signature = + List.iter DeadSign.correct_export signature + in + DeadSign.modtype ~on_mismatch mt + + (******** WRAPPING ********) let expr m = diff --git a/src/deadObj.ml b/src/deadObj.ml index cc131d0..3bdb0be 100644 --- a/src/deadObj.ml +++ b/src/deadObj.ml @@ -215,6 +215,8 @@ let collect_export path u stock ~obj ~cltyp loc = treat_fields save typ | None -> () +let correct_export loc = DeadCommon.unexport decs loc + let collect_references ~meth ~call_site expr = let loc = locate expr in diff --git a/src/deadObj.mli b/src/deadObj.mli index 1602d8c..b5ce97a 100644 --- a/src/deadObj.mli +++ b/src/deadObj.mli @@ -24,6 +24,9 @@ val collect_export : -> Location.t -> unit +val correct_export : Location.t -> unit +(** Undo export collection for the specified location *) + val collect_references : meth: string diff --git a/src/deadSign.ml b/src/deadSign.ml new file mode 100644 index 0000000..e0701f9 --- /dev/null +++ b/src/deadSign.ml @@ -0,0 +1,167 @@ +type context = + | Toplevel + | In_module of (Ident.t * Location.t) + | Include + + +let export_value should_export ~path ~comp_unit ~stock id value = + let loc = value.Types.val_loc in + if should_export then + DeadCommon.export path comp_unit stock id loc; + let path = Ident.create_persistent (Ident.name id ^ "*") :: path in + let obj = value.Types.val_type in + DeadObj.collect_export path comp_unit stock ~obj loc; + !DeadLexiFi.sig_value value + +let export_type ~path ~comp_unit ~stock id t = + let path = id :: path in + DeadType.collect_export path comp_unit stock t + +let export_class ~path ~comp_unit ~stock id cd = + let path = id :: path in + let cltyp = cd.Types.cty_type in + let loc = cd.Types.cty_loc in + DeadObj.collect_export path comp_unit stock ~cltyp loc + +let should_export_value ~context ~stock loc = + let state = State.get_current () in + let belongs_to_context loc = + match context with + | Toplevel | Include -> true + | In_module (_, md_loc) -> + (* When a value is part of a module sig because of an include, + then its location precedes that of the current module. + *) + let get_pos_info loc = + Location.get_pos_info loc.Location.loc_start + in + let v_fname, v_line, v_col = get_pos_info loc in + let md_fname, md_line, md_col = get_pos_info md_loc in + String.equal v_fname md_fname + && (v_line, v_col) > (md_line, md_col) + in + Config.must_report_section state.config.sections.exported_values + && (* do not add the loc in decs if it is not actually declared in + the current context *) + (stock != DeadCommon.decs || belongs_to_context loc) + +let rec collect_export ~context ~path ~comp_unit ~stock sig_item = + match (sig_item : Types.signature_item) with + + | Sig_value (id, ({val_loc; _} as value), _) + when not val_loc.Location.loc_ghost -> + let should_export = should_export_value ~context ~stock val_loc in + export_value should_export ~path ~comp_unit ~stock id value + + | Sig_type (id, t, _, _) when stock == DeadCommon.decs -> + export_type ~path ~comp_unit ~stock id t + + | Sig_class (id, cd, _, _) -> + export_class ~path ~comp_unit ~stock id cd + + | Sig_module (id, _, {Types.md_type = t; md_loc = loc; _}, _, _) -> + let context = + match context with + | Include -> context + | _ -> In_module (id, loc) + in + let path = id :: path in + Utils.signature_of_modtype t + |> List.iter (collect_export ~context ~path ~comp_unit ~stock) + + | _ -> () + + +let rec correct_export : Types.signature_item -> unit = function + | Sig_value (_, {Types.val_loc; _}, _) + when not val_loc.Location.loc_ghost -> + DeadCommon.unexport DeadCommon.decs val_loc; + DeadObj.correct_export val_loc; + (* For optional arguments, every use is stored during the analysis. + The uses are then filtered before reporting. Thus, we need to + remember "wrong" exports until then. + *) + let state = State.get_current () in + if Config.must_report_opt_args state.config then + Hashtbl.replace DeadCommon.implicit_decs val_loc.Location.loc_start () + + | Sig_type (_, t, _, _) -> DeadType.correct_export t + + | Sig_class (_, {cty_loc; _}, _, _) -> DeadObj.correct_export cty_loc + + | Sig_module (_, _, {Types.md_type = t; _}, _, _) + | Sig_modtype (_, {Types.mtd_type = Some t; _}, _) -> + Utils.signature_of_modtype t + |> List.iter correct_export + | _ -> () + + +let modtype ~on_mismatch (mt : Typedtree.module_type) = + let types_sig = Utils.signature_of_modtype mt.mty_type in + let typedtree_sig = Utils.typedtree_signature_of_modtype mt in + match types_sig, typedtree_sig with + | _::_, None -> on_mismatch types_sig + | _ -> () + + +let collect_export_from_typedtree ~path ~comp_unit signature = + let state = State.get_current () in + let should_export_value = + Config.must_report_section state.config.sections.exported_values + in + let mark_modtype_elements mt = + (* For optional arguments, every use is stored during the analysis. + The uses are then filtered before reporting. Thus, we need to + remember "wrong" exports until then. + *) + let on_mismatch signature = List.iter correct_export signature in + if Config.must_report_opt_args state.config then + modtype ~on_mismatch mt + in + let rec collect_signature path Typedtree.{sig_items; _} = + List.iter (collect_item path) sig_items + and collect_item path sig_item = + match sig_item.Typedtree.sig_desc with + + | Tsig_value {val_id; val_loc; val_val; _} + when not val_loc.Location.loc_ghost -> + let stock = DeadCommon.decs in + export_value should_export_value ~path ~comp_unit ~stock val_id val_val + + | Tsig_type (_, type_decls)-> + let stock = DeadCommon.decs in + List.iter + (fun Typedtree.{typ_id; typ_type; _} -> + export_type ~path ~comp_unit ~stock typ_id typ_type + ) + type_decls + + | Tsig_class class_descs -> + let stock = DeadCommon.decs in + List.iter + (fun {Typedtree.ci_id_class; ci_decl; _} -> + export_class ~path ~comp_unit ~stock ci_id_class ci_decl + ) + class_descs + + | Tsig_module {md_id = Some id; md_type; _} -> + let path = id :: path in + Utils.typedtree_signature_of_modtype md_type + |> Option.iter (collect_signature path); + mark_modtype_elements md_type + + | Tsig_include {incl_mod; _} -> + mark_modtype_elements incl_mod + + | _ -> () + in + collect_signature path signature + + +let correct_export sig_item = + let state = State.get_current () in + match state.file_infos.cm_sign with + | Some (Cmti_sign _) -> + (* Typedtree signatures found in .cmti files do not need correction *) + () + | _ -> correct_export sig_item diff --git a/src/deadSign.mli b/src/deadSign.mli new file mode 100644 index 0000000..cd3be03 --- /dev/null +++ b/src/deadSign.mli @@ -0,0 +1,47 @@ +type context = + | Toplevel + | In_module of (Ident.t * Location.t) + | Include + +val collect_export : + context:context -> + path:Ident.t list -> + comp_unit:string -> + stock:(Lexing.position, string * string) Hashtbl.t -> + Types.signature_item + -> unit +(** [collect_export ~context ~path ~comp_unit ~stock sig_item] + recursively traverse the [sig_item] and store exported elements + (values, constructors, ...) in [stock]. + - [path] is the current module path. E.g. for a value in a submodule, + the path is [Module.Submodule]. + - [comp_unit] is the compilation unit of the [sig_item]. + - [context] specifies if the current signature item is found at the + [Toplevel] of the current compilation unit, in a module, a modtype, + or an [Include] +*) + +val correct_export : Types.signature_item -> unit +(** Unexport the signature_item. This is used to correct wrongful exports from + {!collect_export} above +*) + +val collect_export_from_typedtree : + path:Ident.t list -> + comp_unit:string -> + Typedtree.signature + -> unit +(** [collect_export_from_typedtree ~path ~comp_unit sigature] + recursively traverse the [signature] items and store exported elements + (values, constructors, ...) in {!DeadCommon.desc}. + See {!collect_export} above for more information. +*) + +val modtype : + on_mismatch: (Types.signature -> unit) -> + Typedtree.module_type + -> unit +(** [modtype ~on_mismatch mt] checks that the Typedtree and Types signatures + for [mt] agree. I.e. if the first one is explicit when the second one is. + If not, then the first one is implicit and [on_mismatch] is called on the + second. *) diff --git a/src/deadType.ml b/src/deadType.ml index 1a3b99b..668324a 100644 --- a/src/deadType.ml +++ b/src/deadType.ml @@ -94,6 +94,19 @@ let collect_export path u stock t = List.iter (fun {Types.cd_id; cd_loc; _} -> save cd_id cd_loc) l | _ -> () +let correct_export t = + let unexport loc = DeadCommon.unexport decs loc in + match t.type_kind with + | Type_record (l, _) -> + List.iter + (fun {Types.ld_loc; _} -> + unexport ld_loc; + ) + l + | Type_variant (l, _) -> + List.iter (fun {Types.cd_loc; _} -> unexport cd_loc) l + | _ -> () + let collect_references loc exp_loc = LocHash.add_set references loc exp_loc diff --git a/src/deadType.mli b/src/deadType.mli index 28eed7b..a7280fe 100644 --- a/src/deadType.mli +++ b/src/deadType.mli @@ -32,6 +32,9 @@ val collect_export : -> Types.type_declaration -> unit +val correct_export : Types.type_declaration -> unit +(** Undo export collection for the specified type_decl *) + val collect_references : Lexing.position -> Lexing.position -> unit diff --git a/src/state/file_infos.ml b/src/state/file_infos.ml index 89b676e..a9f8eeb 100644 --- a/src/state/file_infos.ml +++ b/src/state/file_infos.ml @@ -1,7 +1,11 @@ +type signature = + | Cmi_sign of Types.signature + | Cmti_sign of Typedtree.signature + type t = { builddir : string; cm_file : string; - cmi_sign : Types.signature option; + cm_sign : signature option; cmt_struct : Typedtree.structure option; cmti_uid_to_decl : Location_dependencies.uid_to_decl option; location_dependencies : Location_dependencies.t; @@ -12,7 +16,7 @@ type t = { let empty = { builddir = "!!UNKNOWN_BUILDDIR!!"; cm_file = ""; - cmi_sign = None; + cm_sign = None; cmt_struct = None; cmti_uid_to_decl = None; location_dependencies = Location_dependencies.empty; @@ -23,7 +27,10 @@ let empty = { (** [init_from_all_cm_infos ~cm_file ~cmi_infos cmt_infos] creates a [t] with: - information from [cmt_infos] : [builddir], [modname], [sourcepath]; - [cm_file]; - - [cmi_sign = Some cm_infos.cmi_sign] if [cmi_infos = Some _]; *) + - [sign] is extracted from either: + - [cmt_infos.cmt_annots] is it is an [Interface] + - [cmi_infos.cmi_sign] if [cmi_infos = Some _] +*) let init_from_all_cm_infos ~cm_file ~cmi_infos cmt_infos = let builddir = cmt_infos.Cmt_format.cmt_builddir in let sourcepath = @@ -31,10 +38,15 @@ let empty = { |> Option.map (Filename.concat builddir) in let modname = cmt_infos.cmt_modname in - let cmi_sign = Option.map (fun Cmi_format.{cmi_sign; _} -> cmi_sign) cmi_infos in + let cm_sign = + match cmt_infos.cmt_annots with + | Interface sign -> Some (Cmti_sign sign) + | _ -> + Option.map (fun Cmi_format.{cmi_sign; _} -> Cmi_sign cmi_sign) cmi_infos + in {empty with builddir; cm_file; - cmi_sign; + cm_sign; modname; sourcepath} @@ -116,7 +128,7 @@ let change_file ~comp_unit_to_path file_infos cm_file = let no_ext = Filename.remove_extension cm_file in assert(no_ext = Filename.remove_extension file_infos.cm_file); match Filename.extension cm_file, file_infos with - | ".cmt", {cmt_struct = (Some _ as cs); cmi_sign; cmti_uid_to_decl; _} -> + | ".cmt", {cmt_struct = (Some _ as cs); cm_sign; cmti_uid_to_decl; _} -> let* res, cmt_infos = init_from_cm_file cm_file in let+ location_dependencies = match file_infos.location_dependencies with @@ -124,7 +136,7 @@ let change_file ~comp_unit_to_path file_infos cm_file = | loc_dep -> (* They have already been computed *) Result.ok loc_dep in - {res with cmt_struct = cs; cmi_sign; cmti_uid_to_decl; location_dependencies} + {res with cmt_struct = cs; cm_sign; cmti_uid_to_decl; location_dependencies} | ".cmti", {cmti_uid_to_decl = (Some _ as cutd); cmt_struct; location_dependencies; _} -> let+ res, _ = init_from_cm_file cm_file in {res with cmti_uid_to_decl = cutd; cmt_struct; location_dependencies} diff --git a/src/state/file_infos.mli b/src/state/file_infos.mli index a4cc8fe..69e25d1 100644 --- a/src/state/file_infos.mli +++ b/src/state/file_infos.mli @@ -1,9 +1,14 @@ (** Information about a analyzable file ([.cmti] or [.cmt] file) *) +type signature = + | Cmi_sign of Types.signature + | Cmti_sign of Typedtree.signature + type t = { builddir : string; (** The [cmt_builddir] *) cm_file : string; (** The filepath currently analyzed *) - cmi_sign : Types.signature option; (** Extracted from [cmi_infos] *) + cm_sign : signature option; + (** Extracted from [cmt_infos] in cmti files and [cmi_infos] in cmt files *) cmt_struct : Typedtree.structure option; (** Extracted from a cmt's [cmt_infos.cmt_annots] *) cmti_uid_to_decl : Location_dependencies.uid_to_decl option; diff --git a/src/utils.ml b/src/utils.ml index df300c1..c52d78e 100644 --- a/src/utils.ml +++ b/src/utils.ml @@ -43,4 +43,12 @@ let rec signature_of_modtype ?(select_param = false) modtype = | Mty_functor (Named (_, t), _) -> signature_of_modtype t | _ -> [] +let rec typedtree_signature_of_modtype ?(select_param = false) modtype = + let open Typedtree in + match modtype.mty_desc with + | Tmty_signature sg -> Some sg + | Tmty_functor (_, t) when not select_param -> typedtree_signature_of_modtype t + | Tmty_functor (Named (_, _, t), _) -> typedtree_signature_of_modtype t + | _ -> None + module StringSet = Set.Make(String) diff --git a/src/utils.mli b/src/utils.mli index 1d506e9..2900bd8 100644 --- a/src/utils.mli +++ b/src/utils.mli @@ -32,4 +32,11 @@ val signature_of_modtype : [false] after looking for the parameter of the first functor. There is currently no way to select the parameter of a parameter. *) +val typedtree_signature_of_modtype : + ?select_param:bool -> Typedtree.module_type -> Typedtree.signature option +(** [signature_of_modtype ?select_param modtype] returns the selected + Typedtree.signature of [modtype] when possible. + See {!signature_of_modtype} above for more information +*) + module StringSet : Set.S with type elt = String.t