123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113(* This file is part of Bisect_ppx, released under the MIT license. See
LICENSE.md for details, or visit
https://github.com/aantron/bisect_ppx/blob/master/LICENSE.md. *)(* Basic types and file [bisect*.coverage] file identifier. Shared with the
reporter. *)typeinstrumented_file={filename:string;points:intarray;counts:intarray;}typecoverage=(string,instrumented_file)Hashtbl.tletcoverage_file_identifier="BISECT-COVERAGE-4"(* Output functions for the [bisect*.coverage] file format. *)letwrite_intbufferi=Buffer.add_charbuffer' ';Buffer.add_stringbuffer(string_of_inti)letwrite_stringbuffers=Buffer.add_charbuffer' ';Buffer.add_stringbuffer(string_of_int(String.lengths));Buffer.add_charbuffer' ';Buffer.add_stringbuffersletwrite_arraywrite_elementbuffera=Buffer.add_charbuffer' ';Buffer.add_stringbuffer(string_of_int(Array.lengtha));Array.iter(write_elementbuffer)aletwrite_listwrite_elementbufferl=Buffer.add_charbuffer' ';Buffer.add_stringbuffer(string_of_int(List.lengthl));List.iter(write_elementbuffer)lletwrite_instrumented_filebuffer{filename;points;counts}=write_stringbufferfilename;write_arraywrite_intbufferpoints;write_arraywrite_intbuffercountsletwrite_coveragecoverage=letbuffer=Buffer.create4096inBuffer.add_stringbuffercoverage_file_identifier;write_listwrite_instrumented_filebuffercoverage;Buffer.contentsbuffer(* Accumulated visit counts. This is used only by the native and ReScript
runtimes. It is idly linked as part of this module into the PPX and reporter,
as well, but not used by them. *)letcoverage:coverageLazy.t=lazy(Hashtbl.create17)letregister_file~filename~points=letfilename=ifFilename.check_suffixfilename".re.ml"thenFilename.chop_suffixfilename".ml"elsefilenameinletcounts=Array.make(Array.lengthpoints)0inletcoverage=Lazy.forcecoverageinifnot(Hashtbl.memcoveragefilename)thenHashtbl.addcoveragefilename{filename;points;counts};`Visit(funindex->letcurrent_count=counts.(index)inifcurrent_count<max_intthencounts.(index)<-current_count+1)letreset_counters()=Hashtbl.iterbeginfun_{counts;_}->matchArray.lengthcountswith|0->()|n->Array.fillcounts0(n-1)0end(Lazy.forcecoverage)(** Helpers for serializing the coverage data in {!coverage}. *)letflatten_coveragecoverage=Hashtbl.fold(fun_fileacc->file::acc)coverage[]letruntime_data_to_string()=matchflatten_coverage(Lazy.forcecoverage)with|[]->None|data->Some(write_coveragedata)letwrite_coveragecoverage=write_coverage(flatten_coveragecoverage)letprng=Random.State.make_self_init()[@coverageoff]letrandom_filename~prefix=prefix^(string_of_int(abs(Random.State.intprng1000000000)))^".coverage"