12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253openStd(** {1 OCaml commandline parsing} *)let{Logger.log}=Logger.for_section"Mconfig"typeocaml={include_dirs:Clflags.visible_includelist;hidden_dirs:stringlist;no_std_include:bool;unsafe:bool;classic:bool;principal:bool;real_paths:bool;threads:[`None|`Threads|`Vmthreads];recursive_types:bool;strict_sequence:bool;applicative_functors:bool;nopervasives:bool;strict_formats:bool;open_modules:stringlist;ppx:stringwith_workdirlist;pp:stringwith_workdiroption;warnings:Warnings.state;cmi_file:stringoption;parameters:stringlist;as_parameter:bool;as_argument_for:stringoption;zero_alloc_check:Zero_alloc_annotations.Check.t;zero_alloc_assert:Zero_alloc_annotations.Assert.t;infer_with_bounds:bool;kind_verbosity:int;ikinds:bool}letdump_warningsst=letst'=Warnings.backup()inWarnings.restorest;Misc.try_finallyWarnings.dump~always:(fun()->Warnings.restorest')letdump_visible_include({path;cmx_guaranteed}:Clflags.visible_include)=`Assoc[("path",`Stringpath);("cmx_guaranteed",`Boolcmx_guaranteed)]letdump_ocamlx=`Assoc[("include_dirs",`List(List.map~f:dump_visible_includex.include_dirs));("hidden_dirs",`List(List.map~f:Json.stringx.hidden_dirs));("no_std_include",`Boolx.no_std_include);("unsafe",`Boolx.unsafe);("classic",`Boolx.classic);("principal",`Boolx.principal);("real_paths",`Boolx.real_paths);("recursive_types",`Boolx.recursive_types);("strict_sequence",`Boolx.strict_sequence);("applicative_functors",`Boolx.applicative_functors);("nopervasives",`Boolx.nopervasives);("strict_formats",`Boolx.strict_formats);("open_modules",Json.listJson.stringx.open_modules);("ppx",Json.list(dump_with_workdirJson.string)x.ppx);("pp",Json.option(dump_with_workdirJson.string)x.pp);("warnings",dump_warningsx.warnings);("cmi_file",Json.optionJson.stringx.cmi_file);("parameters",`List(List.map~f:Json.stringx.parameters));("as_parameter",`Boolx.as_parameter);("zero_alloc_check",`String(Zero_alloc_annotations.Check.to_stringx.zero_alloc_check));("zero_alloc_assert",`String(Zero_alloc_annotations.Assert.to_stringx.zero_alloc_assert));("infer_with_bounds",`Boolx.infer_with_bounds);("kind_verbosity",`Intx.kind_verbosity);("ikinds",`Boolx.ikinds)](** Some paths can be resolved relative to a current working directory *)letcwd=refNoneletunsafe_get_cwd()=match!cwdwith|None->assertfalse|Somecwd->cwdletcanonicalize_filenamepath=Misc.canonicalize_filename?cwd:!cwdpathletmarg_pathf=Marg.param"path"(funpathacc->f(canonicalize_filenamepath)acc)letmarg_commandlinef=Marg.param"command"(funworkvalacc->f{workdir=unsafe_get_cwd();workval}acc)(** {1 Merlin high-level settings} *)typemerlin={build_path:stringlist;source_path:stringlist;hidden_build_path:stringlist;hidden_source_path:stringlist;cmi_path:stringlist;cmt_path:stringlist;index_files:stringlist;extensions:stringlist;suffixes:(string*string)list;stdlib:stringoption;source_root:stringoption;unit_name:stringoption;unit_name_for:stringString.Map.t;wrapping_prefix:stringoption;reader:stringlist;protocol:[`Json|`Sexp];log_file:stringoption;log_sections:stringlist;config_path:stringoption;use_ppx_cache:bool;exclude_query_dir:bool;flags_to_apply:stringlistwith_workdirlist;flags_applied:stringlistwith_workdirlist;failures:stringlist;extension_to_reader:(string*string)list;cache_lifespan:int}letdump_merlinx=letdump_flag_listflags=dump_with_workdir(Json.listJson.string)flagsin`Assoc[("build_path",`List(List.map~f:Json.stringx.build_path));("source_path",`List(List.map~f:Json.stringx.source_path));("hidden_build_path",`List(List.map~f:Json.stringx.hidden_build_path));("hidden_source_path",`List(List.map~f:Json.stringx.hidden_source_path));("cmi_path",`List(List.map~f:Json.stringx.cmi_path));("cmt_path",`List(List.map~f:Json.stringx.cmt_path));("index_files",`List(List.map~f:Json.stringx.index_files));("flags_applied",`List(List.map~f:dump_flag_listx.flags_applied));("extensions",`List(List.map~f:Json.stringx.extensions));("suffixes",`List(List.map~f:(fun(impl,intf)->`Assoc[("impl",`Stringimpl);("intf",`Stringintf)])x.suffixes));("stdlib",Json.optionJson.stringx.stdlib);("source_root",Json.optionJson.stringx.source_root);("unit_name",Json.optionJson.stringx.unit_name);("unit_name_for",letalist=x.unit_name_for|>String.Map.map~f:Json.string|>String.Map.to_listin`Assocalist);("wrapping_prefix",Json.optionJson.stringx.wrapping_prefix);("reader",`List(List.map~f:Json.stringx.reader));("protocol",matchx.protocolwith|`Json->`String"json"|`Sexp->`String"sexp");("log_file",Json.optionJson.stringx.log_file);("log_sections",Json.listJson.stringx.log_sections);("flags_to_apply",`List(List.map~f:dump_flag_listx.flags_to_apply));("failures",`List(List.map~f:Json.stringx.failures));("assoc_suffixes",`List(List.map~f:(fun(suffix,reader)->`Assoc[("extension",`Stringsuffix);("reader",`Stringreader)])x.extension_to_reader));("cache_lifespan",Json.string(string_of_intx.cache_lifespan))]moduleVerbosity=structtypet=Smart|Lvlofintletdefault=Lvl0letto_intt~for_smart=matchtwith|Smart->for_smart|Lvlv->vletparam_spec="\"smart\" | <integer>"letof_string=function|"smart"->Smart|maybe_int->(tryLvl(int_of_stringmaybe_int)with_->invalid_arg("argument should be: "^param_spec))letto_string=function|Smart->"smart"|Lvlv->"lvl "^string_of_intvletto_jsont=`String(to_stringt)endtypequery={filename:string;directory:string;printer_width:int;verbosity:Verbosity.t}letdump_queryx=`Assoc[("filename",`Stringx.filename);("directory",`Stringx.directory);("printer_width",`Intx.printer_width);("verbosity",Verbosity.to_jsonx.verbosity)]typet={ocaml:ocaml;merlin:merlin;query:query}letdumpx=`Assoc[("ocaml",dump_ocamlx.ocaml);("merlin",dump_merlinx.merlin);("query",dump_queryx.query)]letarguments_table=Hashtbl.create67letstdlib=letenv=trySome(Sys.getenv"OCAMLLIB")withNot_found->(trySome(Sys.getenv"CAMLLIB")withNot_found->None)infunconfig->matchconfig.merlin.stdlibwith|Somestdlib->stdlib|None->(matchenvwith|Somestdlib->stdlib|None->Standard_library.path)letnormalize_stept=letmerlin=t.merlininifmerlin.flags_to_apply<>[]thenletflagss=merlin.flags_to_applyinlett={twithmerlin={merlinwithflags_to_apply=[];flags_applied=flagss@merlin.flags_applied}}inletfailures=ref[]inletwarningfailure=failures:=failure::!failuresinlett=List.fold_left~f:(funt{workdir;workval}->fst(let_refcwd(Someworkdir)(Marg.parse_all~warningarguments_table[]workvalt)))~init:tflagssin{twithmerlin={t.merlinwithfailures=!failures@t.merlin.failures}}elsetletis_normalizedt=letmerlin=t.merlininmerlin.flags_to_apply=[]letrecnormalizet=ifis_normalizedtthen(log~title:"normalize""%a"Logger.json(fun()->dumpt);t)elsenormalize(normalize_stept)letmerge_merlin_configdotmerlin~failures~config_path={merlinwithbuild_path=dot.Mconfig_dot.build_path@merlin.build_path;source_path=dot.source_path@merlin.source_path;hidden_build_path=dot.hidden_build_path@merlin.hidden_build_path;hidden_source_path=dot.hidden_source_path@merlin.hidden_source_path;cmi_path=dot.cmi_path@merlin.cmi_path;cmt_path=dot.cmt_path@merlin.cmt_path;index_files=dot.index_files@merlin.index_files;exclude_query_dir=dot.exclude_query_dir||merlin.exclude_query_dir;use_ppx_cache=dot.use_ppx_cache||merlin.use_ppx_cache;extensions=dot.extensions@merlin.extensions;suffixes=dot.suffixes@merlin.suffixes;stdlib=(ifdot.stdlib=Nonethenmerlin.stdlibelsedot.stdlib);unit_name=(ifdot.unit_name=Nonethenmerlin.unit_nameelsedot.unit_name);unit_name_for=String.Map.merge~f:(fun_dotmerlin->match(dot,merlin)with|Somedot,_->Somedot|None,Somemerlin->Somemerlin|None,None->None)dot.unit_name_formerlin.unit_name_for;wrapping_prefix=(ifdot.wrapping_prefix=Nonethenmerlin.wrapping_prefixelsedot.wrapping_prefix);source_root=(ifdot.source_root=Nonethenmerlin.source_rootelsedot.source_root);reader=(ifdot.reader=[]thenmerlin.readerelsedot.reader);flags_to_apply=dot.flags@merlin.flags_to_apply;failures=failures@merlin.failures;config_path=Someconfig_path}letget_external_configpatht=letpath=Misc.canonicalize_filenamepathinletdirectory=Filename.dirnamepathinmatchMconfig_dot.find_project_contextdirectorywith|None->t|Some(ctxt,config_path)->letdot,failures=Mconfig_dot.get_configctxtpathinletmerlin=merge_merlin_configdott.merlin~failures~config_pathinnormalize{twithmerlin}letmerlin_flags=[("-build-path",marg_path(fundirmerlin->{merlinwithbuild_path=dir::merlin.build_path}),"<dir> Add <dir> to merlin build path");("-source-path",marg_path(fundirmerlin->{merlinwithsource_path=dir::merlin.source_path}),"<dir> Add <dir> to merlin source path");("-hidden-build-path",marg_path(fundirmerlin->{merlinwithhidden_build_path=dir::merlin.hidden_build_path}),"<dir> Add <dir> to merlin hidden build path");("-hidden-source-path",marg_path(fundirmerlin->{merlinwithhidden_source_path=dir::merlin.hidden_source_path}),"<dir> Add <dir> to merlin hidden source path");("-cmi-path",marg_path(fundirmerlin->{merlinwithcmi_path=dir::merlin.cmi_path}),"<dir> Add <dir> to merlin cmi path");("-cmt-path",marg_path(fundirmerlin->{merlinwithcmt_path=dir::merlin.cmt_path}),"<dir> Add <dir> to merlin cmt path");("-index-file",marg_path(funfilemerlin->{merlinwithindex_files=file::merlin.index_files}),"<file> Add <file> to the index files used by merlin");("-reader",Marg.param"command"(funreadermerlin->{merlinwithreader=Shell.split_commandreader}),"<command> Use <command> as a merlin reader");("-assocsuffix",Marg.param"suffix:reader"(funassoc_pairmerlin->matchString.split_on_char~sep:':'assoc_pairwith|[suffix;reader]->{merlinwithextension_to_reader=(suffix,reader)::merlin.extension_to_reader}|_->merlin),"Associate suffix with reader");("-addsuffix",Marg.param"implementation Suffix, interface Suffix"(funsuffix_pairmerlin->matchString.split_on_char~sep:':'suffix_pairwith|[impl;intf]->{merlinwithsuffixes=(impl,intf)::merlin.suffixes}|_->merlin),"Add a suffix implementation,interface pair");("-merlin-extension",Marg.param"extension"(funextensionmerlin->matchExtension.lookupextensionwith|None->invalid_arg"Unknown extension"|Some_->{merlinwithextensions=extension::merlin.extensions}),"<extension> Load merlin syntax extension");("-flags",Marg.param"string"(funflagsmerlin->letflags={workdir=unsafe_get_cwd();workval=Shell.split_commandflags}in{merlinwithflags_to_apply=flags::merlin.flags_to_apply}),"<quoted flags> Unescape argument and interpret it as more flags");("-protocol",Marg.param"protocol"(funprotmerlin->matchprotwith|"json"->{merlinwithprotocol=`Json}|"sexp"->{merlinwithprotocol=`Sexp}|_->invalid_arg"Valid protocols are 'json' and 'sexp'"),"<protocol> Select frontend protocol ('json' or 'sexp')");("-log-file",Marg.param"file"(funfilemerlin->{merlinwithlog_file=Somefile}),"<file> Log messages to specified file ('' for disabling, '-' for stderr)");("-log-section",Marg.param"file"(funsectionmerlin->letsections=String.split_on_char_','sectionin{merlinwithlog_sections=sections@merlin.log_sections}),"<section,...> Only log specific sections (separated by comma)");("-ocamllib-path",marg_path(funpathmerlin->{merlinwithstdlib=Somepath}),"<path> Change path of ocaml standard library");("-cache-lifespan",Marg.param"int"(funprotmerlin->try{merlinwithcache_lifespan=int_of_stringprot}with_->invalid_arg"Valid value is int"),"Change file cache retention period. It's measured in minutes. Default \
value is 5.");((* Legacy support for janestreet. Ignored. To be removed soon. *)"-attributes-allowed",Marg.unit_ignore," DEPRECATED")]letquery_flags=[("-verbosity",Marg.paramVerbosity.param_spec(funverbosityquery->letverbosity=Verbosity.of_stringverbosityin{querywithverbosity}),"\"smart\" | <integer> Verbosity determines the number of expansions of \
aliases in answers. \"smart\" is equivalent to verbosity=0 but expands \
module types.");("-printer-width",Marg.param"integer"(funwidthquery->letprinter_width=tryint_of_stringwidthwith_->invalid_arg"argument should be an integer"in{querywithprinter_width}),"<integer> Optimal width for formatting types, signatures, etc")]letocaml_ignored_flags=["-a";"-absname";"-alias-deps";"-annot";"-app-funct";"-bin-annot";"-bin-annot-cms";"-c";"-compact";"-compat-32";"-config";"-custom";"-dclambda";"-dcmm";"-dcse";"-dflambda";"-dflambda-no-invariants";"-dflambda-verbose";"-dinstr";"-dlambda";"-dblambda";"-dlinear";"-dparsetree";"-dshape";"-dtlambda";"-dslambda";"-drawclambda";"-drawflambda";"-drawlambda";"-dsource";"-dstartup";"-dtimings";"-dprofile";"-dtypedtree";"-dtypes";"-dump-pass";"-fno-PIC";"-fPIC";"-g";"-i";"-inlining-report";"-keep-docs";"-no-keep-docs";"-keep-locs";"-linkall";"-requires-metaprogramming";"-uses-metaprogramming";"-make_runtime";"-make-runtime";"-modern";"-no-alias-deps";"-noassert";"-noautolink";"-no-check-prims";"-nodynlink";"-no-float-const-prop";"-no-keep-locs";"-no-principal";"-no-rectypes";"-no-strict-formats";"-no-strict-sequence";"-no-unbox-free-vars-of-clos";"-no-unbox-specialised-args";"-no-unboxed-types";"-O2";"-O3";"-O4";"-Oclassic";"-only-erasable-extensions";"-opaque";"-output-complete-obj";"-output-complete-exe";"-output-obj";"-p";"-pack";"-remove-unused-arguments";"-S";"-shared";"-unbox-closures";"-unboxed-types";"-v";"-verbose";"-where";"-no-absname";"-no-g";"-safe-matching";"-bin-annot-occurrences";(* flambda-backend specific *)"-basic-block-sections";"-caml-apply-inline-fast-path";"-debug-ocaml";"-dgc-timings";"-flambda2-backend-cse-at-toplevel";"-flambda2-debug";"-flambda2-debug-concrete-types-only-on-canonicals";"-flambda2-debug-keep-invalid-handlers";"-flambda2-debug-permute-every-name";"-flambda2-expert-can-inline-recursive-functions";"-flambda2-expert-code-id-and-symbol-scoping-checks";"-flambda2-expert-fallback-inlining-heuristic";"-flambda2-expert-inline-effects-in-cmm";"-flambda2-expert-phantom-lets";"-flambda2-inlining-report-bin";"-flambda2-join-points";"-no-flambda2-result-types";"-flambda2-result-types-all-functions";"-flambda2-result-types-functors-only";"-flambda2-speculative-inlining-only-if-arguments-useful";"-flambda2-unbox-along-intra-function-control-flow";"-flambda2-unicode";"-flambda2-kind-checks";"-no-flambda2-backend-cse-at-toplevel";"-no-flambda2-debug";"-no-flambda2-debug-concrete-types-only-on-canonicals";"-no-flambda2-debug-keep-invalid-handlers";"-no-flambda2-debug-permute-every-name";"-no-flambda2-expert-can-inline-recursive-functions";"-no-flambda2-expert-code-id-and-symbol-scoping-checks";"-no-flambda2-expert-fallback-inlining-heuristic";"-no-flambda2-expert-inline-effects-in-cmm";"-no-flambda2-expert-phantom-lets";"-no-flambda2-join-points";"-no-flambda2-speculative-inlining-only-if-arguments-useful";"-no-flambda2-unbox-along-intra-function-control-flow";"-ocamlcfg";"-no-ocamlcfg";"-regalloc-validate";"-no-regalloc-validate";"-use-cached-generic-functions";"-flambda2-expert-shorten-symbol-names";"-no-flambda2-expert-shorten-symbol-names";"-symbol-visibility-protected";"-no-symbol-visibility-protected";"-flambda2-basic-meet";"-flambda2-advanced-meet";"-directory";"-flambda2-inline-large-functor-size";"-flambda2-inline-small-functor-size";"-flambda2-speculative-inlining-track-lifted-constants";"-name-mangling-scheme";"-no-flambda2-speculative-inlining-track-lifted-constants";(* Jane Street specific *)"-disable-builtin-check";"-disable-poll-insertion";"-gdwarf-may-alter-codegen";"-gno-dwarf-may-alter-codegen";"-davail";"-dranges";"-ddebug-invariants";"-cfg-peephole-optimize";"-no-cfg-peephole-optimize";"-x86-peephole-optimize";"-no-x86-peephole-optimize";"-no-x86-peephole-remove-mov-to-dead-register";"-no-x86-peephole-remove-redundant-cmp";"-no-x86-peephole-combine-add-rsp";"-verbose-types";"-no-verbose-types";"-fsse3";"-fno-sse3";"-fssse3";"-fno-ssse3";"-fsse41";"-fno-sse41";"-fsse42";"-fno-sse42";"-fsimd-regalloc";"-fno-simd-regalloc";"-fclmul";"-fno-clmul";"-no-auto-include-otherlibs";"-fbmi2";"-fno-bmi2";"-fbmi";"-fno-bmi";"-fprefetchwt1";"-fno-prefetchwt1";"-fprefetchw";"-fno-prefetchw";"-fpopcnt";"-fno-popcnt";"-disable-zero-alloc-checker";"-disable-precise-zero-alloc-checker";"-cfg-stack-checks";"-no-cfg-stack-checks";"-gdwarf-inlined-frames";"-gno-dwarf-inlined-frames";"-cfg-stack-checks";"-no-cfg-stack-checks";"-gno-upstream-dwarf";"-dzero-alloc";"-dletreclambda";"-dcounters";"-vectorize";"-no-vectorize";"-dvectorize";"-dump-into-csv";"-no-mach-ir";"-flambda2-reaper";"-no-flambda2-reaper";"-dsimplify";"-dreaper";"-instantiate";"-dflambda-heavy-invariants";"-cfg-eliminate-dead-trap-handlers";"-no-cfg-eliminate-dead-trap-handlers";"-module-entry-functions-section";"-zero-alloc-checker-details-extra";"-no-zero-alloc-checker-details-extra";"-favx512f";"-fno-avx512f";"-favx2";"-fno-avx2";"-favx";"-fno-avx";"-ffma";"-fno-fma";"-ff16c";"-fno-f16c";"-dllvmir";"-keep-llvmir";"-llvm-backend";"-no-llvm-backend";"-ddwarf-types";"-ocamlcfg";"-cfg-prologue-validate";"-no-cfg-prologue-validate";"-cfg-prologue-shrink-wrap";"-no-cfg-prologue-shrink-wrap";"-cfg-merge-blocks";"-no-cfg-merge-blocks";"-cfg-value-propagation";"-no-cfg-value-propagation";"-cfg-value-propagation-float";"-no-cfg-value-propagation-float";"-cfg-value-propagation-flow";"-no-cfg-value-propagation-flow";"-gdwarf-pedantic";"-ddwarf-metrics";"-afl-instrument";"-probes";"-no-probes";"-probes-optimized";"-no-probes-optimized";"-disable-all-extensions";"-nocwd";"-with-runtime";"-without-runtime";"-ddebug-uids";"-ddebug-uid-tables";"-version";"--version";"-vnum";"-warn-help";"-help";"--help";"-match-context-rows";"-safer-matching";"-dno-unique-ids";"-dunique-ids";"-dno-locations";"-dlocations";"-dcamlprimc";"-dtimings-precision";"-dprofile-output";"-locs";"-no-locs";"-flzcnt";"-fno-lzcnt";"-reaper-local-fields";"-no-reaper-local-fields";"-reaper-unbox";"-no-reaper-unbox";"-reaper-max-unbox-size";"-reaper-change-calling-conventions";"-no-reaper-change-calling-conventions";"-flambda2-expert-cmm-safe-subst";"-no-flambda2-expert-cmm-safe-subst";"-dissector";"-ddissector";"-ddissector-sizes";"-ddissector-verbose";"-ddissector-partitions";"-dissector-assume-lld-without-64-bit-eh-frames";"-no-dissector-assume-lld-without-64-bit-eh-frames";"-manual-module-init";"-no-manual-module-init";"-dfexpr-annot";"-dfexpr-annot-after";"-linscan";"-clambda-checks";"-dasm-comments";"-dcfg";"-dcfg-invariants";"-dcmm-invariants";"-ddebug-available-regs";"-dfexpr";"-dflambda-invariants";"-dflow";"-dfreshen";"-dno-asm-comments";"-drawfexpr";"-dslot-offsets";"-dump-inlining-paths";"-enable-poll-insertion";"-fno-asan";"-fno-trap-notes";"-ftrap-notes";"-function-sections";"-gdwarf-may-alter-codegen-experimental";"-gno-dwarf-may-alter-codegen-experimental";"-gno-startup";"-gstartup";"-gupstream-dwarf";"-insn-sched";"-internal-assembler";"-long-frames";"-no-insn-sched";"-no-long-frames";"-no-unbox-free-vars-of-closures";"-verify-binary-emitter";"-ikinds-debug";"-thunkify-compilation-unit-initialization"]letocaml_ignored_parametrized_flags=["-cc";"-cclib";"-ccopt";"-color";"-dflambda-let";"-dllib";"-dllpath";"-for-pack";"-impl";"-inline-alloc-cost";"-inline-branch-cost";"-inline-branch-factor";"-inline-call-cost";"-inline-indirect-cost";"-inline-lifting-benefit";"-inline-max-depth";"-inline-max-unroll";"-inline";"-inline-prim-cost";"-inline-toplevel";"-intf";"-intf_suffix";"-intf-suffix";"-o";"-rounds";"-runtime-variant";"-ocamlrunparam";"-unbox-closures-factor";"-use-prims";"-use_runtime";"-use-runtime";"-error-style";"-dump-dir";"-I-manifest";"-H-manifest";(* flambda-backend specific *)"-extension";"-extension-universe";"-no-extension";"-drawfexpr-to";"-dfexpr-to";"-reorder-blocks-random";"-heap-reduction-threshold";"-flambda2-cse-depth";"-flambda2-expert-max-block-size-for-projections";"-flambda2-expert-max-unboxing-depth";"-flambda2-join-depth";"-flambda2-inline-alloc-cost";"-flambda2-inline-branch-cost";"-flambda2-inline-call-cost";"-flambda2-inline-indirect-cost";"-flambda2-inline-large-function-size";"-flambda2-inline-max-depth";"-flambda2-inline-max-rec-depth";"-flambda2-inline-poly-compare-cost";"-flambda2-inline-prim-cost";"-flambda2-inline-small-function-size";"-flambda2-inline-threshold";"-flambda2-join-algorithm";"-flambda2-expert-cont-specialization-budget";"-regalloc";"-regalloc-linscan-threshold";"-regalloc-param";"-cached-generic-functions-path";"-gdwarf-max-function-complexity";"-function-layout";"-cfg-stack-checks-threshold";"-zero-alloc-checker-details-cutoff";"-zero-alloc-checker-join";"-dgranularity";"-flambda2-expert-cont-lifting-budget";"-vectorize-max-block-size";"-save-ir-before";"-shape-format";"-gdwarf-compression";"-gdwarf-fission";"-cfg-prologue-shrink-wrap-threshold";"-gdwarf-config-shape-reduce-depth";"-gdwarf-config-shape-eval-depth";"-gdwarf-config-max-cms-files-per-unit";"-gdwarf-config-max-cms-files-per-variable";"-gdwarf-config-max-type-to-shape-depth";"-gdwarf-config-max-shape-reduce-steps-per-variable";"-gdwarf-config-max-evaluation-steps-per-variable";"-gdwarf-config-shape-reduce-fuel";"-gdwarf-fidelity";"-llvm-path";"-afl-inst-ratio";"-config-var";"-stop-after";"-plugin";"-dump-into-file";"-ddwarf-metrics-output-file";"-reaper-debug-flags";"-dissector-partition-size";"-ddissector-inputs";"-dfexpr-after";"-debug-long-frames-threshold";"-flambda2-expert-max-function-simplify-run";"-llvm-flags";"-reaper-preserve-direct-calls";"-save-ir-after"]letocaml_warnings_spec~error=Marg.param"warning specification"(funspecocaml->letb'=Warnings.backup()inWarnings.restoreocaml.warnings;Misc.try_finally(fun()->ignore@@Warnings.parse_optionserrorspec;{ocamlwithwarnings=Warnings.backup()})~always:(fun()->Warnings.restoreb'))letocaml_alert_spec=Marg.param"alert specification"(funspecocaml->letb'=Warnings.backup()inWarnings.restoreocaml.warnings;Misc.try_finally(fun()->Warnings.parse_alert_optionspec;{ocamlwithwarnings=Warnings.backup()})~always:(fun()->Warnings.restoreb'))letocaml_flags=[("-I",marg_path(funpathocaml->{ocamlwithinclude_dirs={path;cmx_guaranteed=false}::ocaml.include_dirs}),"<dir> Add <dir> to the list of include directories");("-Ix",marg_path(funpathocaml->{ocamlwithinclude_dirs={path;cmx_guaranteed=true}::ocaml.include_dirs}),"<dir> Add <dir> to the list of include directories (Like -I, but \
indicates that cmx files for modules in <dir> are always available)");("-H",marg_path(fundirocaml->{ocamlwithhidden_dirs=dir::ocaml.hidden_dirs}),"<dir> Add <dir> to the list of \"hidden\" include directories\n\
\ (Like -I, but the program can not directly reference these \
dependencies)");("-nostdlib",Marg.unit(funocaml->{ocamlwithno_std_include=true})," Do not add default directory to the list of include directories");("-unsafe",Marg.unit(funocaml->{ocamlwithunsafe=true})," Do not compile bounds checking on array and string access");("-labels",Marg.unit(funocaml->{ocamlwithclassic=false})," Use commuting label mode");("-nolabels",Marg.unit(funocaml->{ocamlwithclassic=true})," Ignore non-optional labels in types");("-principal",Marg.unit(funocaml->{ocamlwithprincipal=true})," Check principality of type inference");("-real-paths",Marg.unit(funocaml->{ocamlwithreal_paths=true})," Display real paths in types rather than short ones");("-short-paths",Marg.unit(funocaml->{ocamlwithreal_paths=false})," Shorten paths in types");("-rectypes",Marg.unit(funocaml->{ocamlwithrecursive_types=true})," Allow arbitrary recursive types");("-strict-sequence",Marg.unit(funocaml->{ocamlwithstrict_sequence=true})," Left-hand part of a sequence must have type unit");("-no-app-funct",Marg.unit(funocaml->{ocamlwithapplicative_functors=false})," Deactivate applicative functors");("-thread",Marg.unit(funocaml->{ocamlwiththreads=`Threads})," Add support for system threads library");("-vmthread",Marg.unit(funocaml->{ocamlwiththreads=`None})," Add support for VM-scheduled threads library");("-safe-string",Marg.unit(funocaml->ocaml)," Default to true unconditionally since 5.00");("-nopervasives",Marg.unit(funocaml->{ocamlwithnopervasives=true})," Don't open Pervasives module (advanced)");("-strict-formats",Marg.unit(funocaml->{ocamlwithstrict_formats=true})," Reject invalid formats accepted by legacy implementations");("-open",Marg.param"module"(funmdocaml->{ocamlwithopen_modules=md::ocaml.open_modules}),"<module> Opens the module <module> before typing");("-ppx",marg_commandline(funcommandocaml->{ocamlwithppx=command::ocaml.ppx}),"<command> Pipe abstract syntax trees through preprocessor <command>");("-pp",marg_commandline(funppocaml->{ocamlwithpp=Somepp}),"<command> Pipe sources through preprocessor <command>");("-w",ocaml_warnings_spec~error:false,Printf.sprintf"<list> Enable or disable warnings according to <list>:\n\
\ +<spec> enable warnings in <spec>\n\
\ -<spec> disable warnings in <spec>\n\
\ @<spec> enable warnings in <spec> and treat them as errors\n\
\ <spec> can be:\n\
\ <num> a single warning number\n\
\ <num1>..<num2> a range of consecutive warning numbers\n\
\ <letter> a predefined set\n\
\ default setting is %S"Warnings.defaults_w);("-warn-error",ocaml_warnings_spec~error:true,Printf.sprintf"<list> Enable or disable error status for warnings according\n\
\ to <list>. See option -w for the syntax of <list>.\n\
\ Default setting is %S"Warnings.defaults_warn_error);("-alert",ocaml_alert_spec,Printf.sprintf"<list> Enable or disable alerts according to <list>:\n\
\ +<alertname> enable alert <alertname>\n\
\ -<alertname> disable alert <alertname>\n\
\ ++<alertname> treat <alertname> as fatal error\n\
\ --<alertname> treat <alertname> as non-fatal\n\
\ @<alertname> enable <alertname> and treat it as fatal error\n\
\ <alertname> can be 'all' to refer to all alert names");("-cmi-file",Marg.param"file"(funcmi_fileocaml->{ocamlwithcmi_file=Somecmi_file}),"<file> Use the <file> interface to type-check");("-parameter",Marg.param"module name"(funparameterocaml->{ocamlwithparameters=parameter::ocaml.parameters}),"<module name> Compile the module with <module name> as a parameter.");("-as-parameter",Marg.unit(funocaml->{ocamlwithas_parameter=true})," Compile the interface as a parameter module.");("-as-argument-for",Marg.param"module name"(funas_argument_forocaml->{ocamlwithas_argument_for=Someas_argument_for}),"<module name> Compile the module as an argument for the named parameter.");("-zero-alloc-check",Marg.param"string"(funzero_alloc_strocaml->matchZero_alloc_annotations.Check.of_stringzero_alloc_strwith|Somezero_alloc_check->{ocamlwithzero_alloc_check}|None->failwith("Invalid value for -zero-alloc-check: "^zero_alloc_str))," Check that annotated functions do not allocate and do not have \
indirect calls. "^Zero_alloc_annotations.Check.doc);("-zero-alloc-assert",Marg.param"string"(funzero_alloc_strocaml->matchZero_alloc_annotations.Assert.of_stringzero_alloc_strwith|Somezero_alloc_assert->{ocamlwithzero_alloc_assert}|None->failwith("Invalid value for -zero-alloc-assert: "^zero_alloc_str))," Add zero_alloc annotations to all functions. "^Zero_alloc_annotations.Assert.doc);("-infer-with-bounds",Marg.unit(funocaml->{ocamlwithinfer_with_bounds=true}),"Infer with-bounds on kinds for type declarations. May impact \
performance.");("-kind-verbosity",Marg.int(funkind_verbosityocaml->{ocamlwithkind_verbosity}),"Set the verbosity used for printing kinds (0=not verbose, 1=expanded, \
2=expanded with all mod bounds)");("-no-ikinds",Marg.bool(funno_ikindsocaml->{ocamlwithikinds=notno_ikinds}),"Disable ikinds-based kind checker")](** {1 Main configuration} *)letinitial={ocaml={include_dirs=[];hidden_dirs=[];no_std_include=false;unsafe=false;classic=false;principal=false;real_paths=true;threads=`None;recursive_types=false;strict_sequence=false;applicative_functors=true;nopervasives=false;strict_formats=false;open_modules=[];ppx=[];pp=None;warnings=Warnings.backup();cmi_file=None;parameters=[];as_parameter=false;as_argument_for=None;zero_alloc_check=Zero_alloc_annotations.Check.Check_default;zero_alloc_assert=Zero_alloc_annotations.Assert.Assert_default;infer_with_bounds=false;kind_verbosity=0;ikinds=false};merlin={build_path=[];source_path=[];hidden_build_path=[];hidden_source_path=[];cmi_path=[];cmt_path=[];index_files=[];extensions=[];suffixes=[(".ml",".mli");(".re",".rei")];stdlib=None;source_root=None;unit_name=None;unit_name_for=String.Map.empty;wrapping_prefix=None;reader=[];protocol=`Json;log_file=None;log_sections=[];config_path=None;exclude_query_dir=false;use_ppx_cache=false;flags_to_apply=[];flags_applied=[];failures=[];extension_to_reader=[(".re","reason");(".rei","reason")];cache_lifespan=5};query={filename="*buffer*";directory=Sys.getcwd();verbosity=Verbosity.default;printer_width=0}}letparse_arguments~wd~warninglocal_specargstlocal=let_refcwd(Somewd)@@fun()->Marg.parse_all~warningarguments_tablelocal_specargstlocalletglobal_flags=[("-filename",marg_path(funpatht->letquery=t.queryinletpath=Misc.canonicalize_filenamepathinletfilename=Filename.basenamepathinletdirectory=Filename.dirnamepathinlett={twithquery={querywithfilename;directory}}inLogger.with_log_filet.merlin.log_file~sections:t.merlin.log_sections@@fun()->get_external_configpatht),"<path> Path of the buffer; extension determines the kind of file \
(interface or implementation), basename is used as name of the module \
being definer, directory is used to resolve other relative paths");("-dot-merlin",marg_path(fundotmerlint->get_external_configdotmerlint),"<path> Load <path> as a .merlin; if it is a directory, look for .merlin \
here or in a parent directory")]let()=List.iter~f:(funname->Hashtbl.addarguments_tablenameMarg.unit_ignore)ocaml_ignored_flags;List.iter~f:(funname->Hashtbl.addarguments_tablenameMarg.param_ignore)ocaml_ignored_parametrized_flags;letlensprjupdflag:_Marg.t=funargsa->letcwd'=match!cwdwith|Nonewhena.query.directory<>""->Somea.query.directory|cwd->cwdinlet_refcwdcwd'@@fun()->letargs,b=flagargs(prja)in(args,updab)inletaddprjupd(name,flag,_doc)=ifHashtbl.memarguments_tablenamethenfailwith("Duplicate flag spec: "^name);Hashtbl.addarguments_tablename(lensprjupdflag)inList.iter~f:(add(funx->x.ocaml)(funxocaml->{xwithocaml}))ocaml_flags;List.iter~f:(add(funx->x.merlin)(funxmerlin->{xwithmerlin}))merlin_flags;List.iter~f:(add(funx->x.query)(funxquery->{xwithquery}))query_flags;List.iter~f:(add(funx->x)(fun_x->x))global_flagsletflags_for_completion()=List.sort~cmp:compare("-dot-merlin"::"-reader"::List.map~f:(fun(x,_,_)->x)ocaml_flags)letdocument_argumentsoc=letprint_docflags=List.iter~f:(fun(name,_flag,doc)->Printf.fprintfoc" %s\t%s\n"namedoc)flagsinoutput_stringoc"Flags affecting Merlin:\n";print_docmerlin_flags;print_docquery_flags;output_stringoc"Flags affecting OCaml frontend:\n";print_dococaml_flags;output_stringoc"Flags accepted by ocamlc and ocamlopt but not affecting merlin will be \
ignored.\n"letsource_pathconfig=letstdlib=ifconfig.ocaml.no_std_includethen[]else[stdlibconfig]inList.concat[[config.query.directory];stdlib;config.merlin.source_path;config.merlin.hidden_source_path]|>List.filter_duplethidden_source_pathconfig=config.merlin.hidden_source_path@config.ocaml.hidden_dirsletcollect_paths~log_title~configpaths=letinclude_dirs=List.mapconfig.ocaml.include_dirs~f:(fun(vi:Clflags.visible_include)->vi.path)inletdirs=matchconfig.ocaml.threadswith|`None->include_dirs|`Threads->"+threads"::include_dirs|`Vmthreads->"+vmthreads"::include_dirsinletdirs=paths@dirsinletstdlib=stdlibconfiginletexp_dirs=List.map~f:(Misc.expand_directorystdlib)dirsinletstdlib=ifconfig.ocaml.no_std_includethen[]else[stdlib]inletdirs=List.rev_appendexp_dirsstdlibinletresult=ifconfig.merlin.exclude_query_dirthendirselseconfig.query.directory::dirsinletresult=List.filter_dupresultinlog~title:log_title"%d items in path, %d after deduplication"(List.lengthresult)(List.lengthresult);resultletbuild_pathconfig=collect_paths~log_title:"build_path"~config(config.merlin.cmi_path@config.merlin.build_path)lethidden_build_pathconfig=config.merlin.hidden_build_path@config.ocaml.hidden_dirsletcmt_pathconfig=collect_paths~log_title:"cmt_path"~config(config.merlin.cmt_path@config.merlin.build_path@config.merlin.hidden_build_path)letglobal_modules?(include_current=false)config=letmodules=modules_in_path~ext:".cmi"(build_pathconfig)inifinclude_currentthenmoduleselsematchconfig.query.filenamewith|""->modules|filename->List.remove(unitnamefilename)modules(** {1 Accessors for other information} *)letfilenamet=t.query.filenameletunitnamet=matcht.merlin.unit_namewith|Somename->unitnamename|None->letbasename=unitnamet.query.filenamein(* CR: get rid of wrapping_prefix. it is only here for legacy reasons at the moment *)beginmatcht.merlin.wrapping_prefixwith|Someprefix->unitname(prefix^basename)|None->String.Map.find_optbasenamet.merlin.unit_name_for|>Option.map~f:unitname|>Option.value~default:basenameend