├── .git-blame-ignore-revs ├── .gitattributes ├── .github ├── dependabot.yml ├── fuzzy-ci-helpers │ ├── create_diff.ml │ ├── irmin.3.10.0.opam.locked │ ├── label_name.txt │ └── msg.txt └── workflows │ ├── changelog.yml │ ├── emacs-lint.yml │ ├── fuzzy-ci-privileged.yml │ ├── fuzzy-ci.yml │ ├── main.yml │ ├── nix.yml │ └── ocaml-lsp-compat.yml ├── .gitignore ├── .ocamlformat ├── .ocamlformat-ignore ├── CHANGES.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── Makefile ├── README.md ├── RELEASE.md ├── appveyor.cmd ├── appveyor.sh ├── appveyor.yml ├── appveyor ├── easy-format-1.2.0.patch └── findlib-1.7.3.patch ├── bench.Dockerfile ├── bench └── irmin.opam.export ├── doc ├── dev │ ├── ARCHITECTURE.md │ ├── CACHING.md │ ├── OLD-PROTOCOL.md │ ├── PROTOCOL.md │ └── SERVER.md ├── features.md ├── next │ ├── Protocol.wiki │ ├── RATIONALE.wiki │ └── merlin.wiki └── pres │ └── pres-meetup-21-05-13.tex ├── dot-merlin-reader.opam ├── dune-project ├── dune-release.sh ├── emacs ├── check.sh ├── dune ├── merlin-ac.el ├── merlin-cap.el ├── merlin-company.el ├── merlin-iedit.el ├── merlin-imenu.el ├── merlin-xref.el └── merlin.el ├── featuremap.tines ├── featuremap.txt ├── flake.lock ├── flake.nix ├── merlin-lib.opam ├── merlin.opam ├── ocaml-index.opam ├── src ├── analysis │ ├── ast_iterators.ml │ ├── browse_misc.ml │ ├── browse_tree.ml │ ├── browse_tree.mli │ ├── completion.ml │ ├── completion.mli │ ├── construct.ml │ ├── construct.mli │ ├── context.ml │ ├── context.mli │ ├── destruct.ml │ ├── destruct.mli │ ├── dune │ ├── env_lookup.ml │ ├── env_lookup.mli │ ├── expansion.ml │ ├── expansion.mli │ ├── index_occurrences.ml │ ├── inlay_hints.ml │ ├── inlay_hints.mli │ ├── jump.ml │ ├── jump.mli │ ├── locate.ml │ ├── locate.mli │ ├── misc_utils.ml │ ├── misc_utils.mli │ ├── ocamldoc.ml │ ├── occurrences.ml │ ├── occurrences.mli │ ├── outline.ml │ ├── outline.mli │ ├── parsetree_utils.ml │ ├── parsetree_utils.mli │ ├── polarity_search.ml │ ├── ppx_expand.ml │ ├── ppx_expand.mli │ ├── ptyp_of_type.ml │ ├── ptyp_of_type.mli │ ├── refactor_open.ml │ ├── refactor_open.mli │ ├── signature_help.ml │ ├── signature_help.mli │ ├── syntax_doc.ml │ ├── syntax_doc.mli │ ├── tail_analysis.ml │ ├── tail_analysis.mli │ ├── type_enclosing.ml │ ├── type_enclosing.mli │ ├── type_search.ml │ ├── type_search.mli │ ├── type_utils.ml │ ├── type_utils.mli │ ├── typed_hole.ml │ ├── typed_hole.mli │ ├── typedtree_utils.ml │ └── typedtree_utils.mli ├── commands │ ├── dune │ ├── new_commands.ml │ ├── new_commands.mli │ └── query_json.ml ├── config │ ├── dune │ └── gen_config.ml ├── dot-merlin │ ├── dot_merlin_reader.ml │ └── dune ├── dot-protocol │ ├── dune │ ├── merlin_dot_protocol.ml │ └── merlin_dot_protocol.mli ├── extend │ ├── .gitignore │ ├── dune │ ├── extend_driver.ml │ ├── extend_driver.mli │ ├── extend_helper.ml │ ├── extend_helper.mli │ ├── extend_main.ml │ ├── extend_main.mli │ └── extend_protocol.ml ├── frontend │ ├── dune │ ├── ocamlmerlin │ │ ├── dune │ │ ├── gen_ccflags.ml │ │ ├── log_info.ml │ │ ├── log_info.mli │ │ ├── new │ │ │ └── new_merlin.ml │ │ ├── ocamlmerlin.c │ │ ├── ocamlmerlin_server.ml │ │ └── old │ │ │ ├── old_IO.ml │ │ │ ├── old_IO.mli │ │ │ ├── old_command.ml │ │ │ ├── old_command.mli │ │ │ ├── old_merlin.ml │ │ │ ├── old_merlin.mli │ │ │ └── old_protocol.ml │ ├── query_commands.ml │ ├── query_commands.mli │ ├── query_protocol.ml │ └── test │ │ └── ocamlmerlin_test.ml ├── index-format │ ├── dune │ ├── granular_map.ml │ ├── granular_map.mli │ ├── granular_marshal.ml │ ├── granular_marshal.mli │ ├── granular_set.ml │ ├── granular_set.mli │ ├── index_cache.ml │ ├── index_format.ml │ ├── index_format.mli │ ├── lid.ml │ └── union_find.ml ├── kernel │ ├── dune │ ├── extension.ml │ ├── extension.mli │ ├── mbrowse.ml │ ├── mbrowse.mli │ ├── mconfig.ml │ ├── mconfig.mli │ ├── mconfig_dot.ml │ ├── mconfig_dot.mli │ ├── mocaml.ml │ ├── mocaml.mli │ ├── mpipeline.ml │ ├── mpipeline.mli │ ├── mppx.ml │ ├── mppx.mli │ ├── mreader.ml │ ├── mreader.mli │ ├── mreader_explain.ml │ ├── mreader_extend.ml │ ├── mreader_extend.mli │ ├── mreader_lexer.ml │ ├── mreader_lexer.mli │ ├── mreader_parser.ml │ ├── mreader_parser.mli │ ├── mreader_recover.ml │ ├── mreader_recover.mli │ ├── msource.ml │ ├── msource.mli │ ├── mtyper.ml │ ├── mtyper.mli │ ├── phase_cache.ml │ └── phase_cache.mli ├── ocaml-index │ ├── CHANGES.md │ ├── README.md │ ├── bin │ │ ├── dune │ │ └── ocaml_index.ml │ ├── lib │ │ ├── dune │ │ ├── index.ml │ │ ├── log.ml │ │ └── log.mli │ └── tests │ │ ├── dune │ │ └── tests-dirs │ │ ├── cmd.t │ │ ├── flags.t │ │ ├── index-project.t │ │ ├── interfaces.t │ │ ├── local-shape-and-include.t │ │ └── transitive-deps.t ├── ocaml │ ├── .ocamlformat │ ├── .ocamlformat-enable │ ├── compression │ │ ├── dune │ │ └── ocaml_compression.ml │ ├── driver │ │ ├── pparse.ml │ │ └── pparse.mli │ ├── merlin_specific │ │ ├── browse_raw.ml │ │ ├── browse_raw.mli │ │ ├── dune │ │ ├── tast_helper.ml │ │ ├── typer_raw.ml │ │ └── typer_raw.mli │ ├── parsing │ │ ├── .ocamlformat-enable │ │ ├── ast_helper.ml │ │ ├── ast_helper.mli │ │ ├── ast_iterator.ml │ │ ├── ast_iterator.mli │ │ ├── ast_mapper.ml │ │ ├── ast_mapper.mli │ │ ├── asttypes.ml │ │ ├── asttypes.mli │ │ ├── attr_helper.ml │ │ ├── attr_helper.mli │ │ ├── builtin_attributes.ml │ │ ├── builtin_attributes.mli │ │ ├── docstrings.ml │ │ ├── docstrings.mli │ │ ├── dune │ │ ├── fake.ml │ │ ├── fake.mli │ │ ├── lexer.ml │ │ ├── location.ml │ │ ├── location.mli │ │ ├── location_aux.ml │ │ ├── location_aux.mli │ │ ├── longident.ml │ │ ├── longident.mli │ │ ├── msupport_parsing.ml │ │ ├── parsetree.mli │ │ ├── pprintast.ml │ │ ├── pprintast.mli │ │ ├── printast.ml │ │ ├── printast.mli │ │ ├── syntaxerr.ml │ │ ├── syntaxerr.mli │ │ ├── unit_info.ml │ │ └── unit_info.mli │ ├── preprocess │ │ ├── dune │ │ ├── explain │ │ │ ├── dune │ │ │ └── gen_explain.ml │ │ ├── lexer_ident.mli │ │ ├── lexer_ident.mll │ │ ├── lexer_raw.mli │ │ ├── lexer_raw.mll │ │ ├── menhirLib.ml │ │ ├── menhirLib.mli │ │ ├── parser_explain.ml │ │ ├── parser_printer.ml │ │ ├── parser_printer.mli │ │ ├── parser_raw.ml │ │ ├── parser_raw.mli │ │ ├── parser_raw.mly │ │ ├── parser_recover.ml │ │ ├── parser_recover.mli │ │ ├── printer │ │ │ ├── dune │ │ │ └── gen_printer.ml │ │ └── recover │ │ │ ├── compressedBitSet.ml │ │ │ ├── compressedBitSet.mli │ │ │ ├── dune │ │ │ ├── emitter.ml │ │ │ ├── emitter.mli │ │ │ ├── fix.ml │ │ │ ├── fix.mli │ │ │ ├── gSet.ml │ │ │ ├── gen_recover.ml │ │ │ ├── journal.md │ │ │ ├── recover_attrib.ml │ │ │ ├── recover_attrib.mli │ │ │ ├── recovery.ml │ │ │ ├── recovery.mli │ │ │ ├── synthesis.ml │ │ │ ├── synthesis.mli │ │ │ └── utils.ml │ ├── typing │ │ ├── .ocamlformat-enable │ │ ├── annot.mli │ │ ├── btype.ml │ │ ├── btype.mli │ │ ├── cmi_cache.ml │ │ ├── cmi_format.ml │ │ ├── cmi_format.mli │ │ ├── cmt_cache.ml │ │ ├── cmt_format.ml │ │ ├── cmt_format.mli │ │ ├── ctype.ml │ │ ├── ctype.mli │ │ ├── datarepr.ml │ │ ├── datarepr.mli │ │ ├── dune │ │ ├── env.ml │ │ ├── env.mli │ │ ├── envaux.ml │ │ ├── envaux.mli │ │ ├── errortrace.ml │ │ ├── errortrace.mli │ │ ├── errortrace_report.ml │ │ ├── errortrace_report.mli │ │ ├── ident.ml │ │ ├── ident.mli │ │ ├── includeclass.ml │ │ ├── includeclass.mli │ │ ├── includecore.ml │ │ ├── includecore.mli │ │ ├── includemod.ml │ │ ├── includemod.mli │ │ ├── includemod_errorprinter.ml │ │ ├── includemod_errorprinter.mli │ │ ├── lambda.ml │ │ ├── magic_numbers.ml │ │ ├── msupport.ml │ │ ├── msupport.mli │ │ ├── mtype.ml │ │ ├── mtype.mli │ │ ├── natural.ml │ │ ├── natural.mli │ │ ├── oprint.ml │ │ ├── oprint.mli │ │ ├── out_type.ml │ │ ├── out_type.mli │ │ ├── outcometree.mli │ │ ├── parmatch.ml │ │ ├── parmatch.mli │ │ ├── path.ml │ │ ├── path.mli │ │ ├── patterns.ml │ │ ├── patterns.mli │ │ ├── persistent_env.ml │ │ ├── persistent_env.mli │ │ ├── predef.ml │ │ ├── predef.mli │ │ ├── primitive.ml │ │ ├── primitive.mli │ │ ├── printpat.ml │ │ ├── printpat.mli │ │ ├── printtyp.ml │ │ ├── printtyp.mli │ │ ├── printtyped.ml │ │ ├── printtyped.mli │ │ ├── rawprinttyp.ml │ │ ├── rawprinttyp.mli │ │ ├── saved_parts.ml │ │ ├── saved_parts.mli │ │ ├── shape.ml │ │ ├── shape.mli │ │ ├── shape_reduce.ml │ │ ├── shape_reduce.mli │ │ ├── short_paths.ml │ │ ├── short_paths.mli │ │ ├── short_paths_graph.ml │ │ ├── short_paths_graph.mli │ │ ├── signature_group.ml │ │ ├── signature_group.mli │ │ ├── stypes.ml │ │ ├── stypes.mli │ │ ├── subst.ml │ │ ├── subst.mli │ │ ├── tast_iterator.ml │ │ ├── tast_iterator.mli │ │ ├── tast_mapper.ml │ │ ├── tast_mapper.mli │ │ ├── type_immediacy.ml │ │ ├── type_immediacy.mli │ │ ├── typeclass.ml │ │ ├── typeclass.mli │ │ ├── typecore.ml │ │ ├── typecore.mli │ │ ├── typedecl.ml │ │ ├── typedecl.mli │ │ ├── typedecl_immediacy.ml │ │ ├── typedecl_immediacy.mli │ │ ├── typedecl_properties.ml │ │ ├── typedecl_properties.mli │ │ ├── typedecl_separability.ml │ │ ├── typedecl_separability.mli │ │ ├── typedecl_unboxed.ml │ │ ├── typedecl_unboxed.mli │ │ ├── typedecl_variance.ml │ │ ├── typedecl_variance.mli │ │ ├── typedtree.ml │ │ ├── typedtree.mli │ │ ├── typemod.ml │ │ ├── typemod.mli │ │ ├── typeopt.ml │ │ ├── typeopt.mli │ │ ├── types.ml │ │ ├── types.mli │ │ ├── typetexp.ml │ │ ├── typetexp.mli │ │ ├── untypeast.ml │ │ ├── untypeast.mli │ │ ├── value_rec_check.ml │ │ ├── value_rec_check.mli │ │ └── value_rec_types.mli │ └── utils │ │ ├── build_path_prefix_map.ml │ │ ├── build_path_prefix_map.mli │ │ ├── clflags.ml │ │ ├── clflags.mli │ │ ├── compression.ml │ │ ├── compression.mli │ │ ├── config.common.ml.in │ │ ├── config.fixed.ml │ │ ├── config.generated.ml.in │ │ ├── config.ml │ │ ├── config.mli │ │ ├── consistbl.ml │ │ ├── consistbl.mli │ │ ├── diffing.ml │ │ ├── diffing.mli │ │ ├── diffing_with_keys.ml │ │ ├── diffing_with_keys.mli │ │ ├── directory_content_cache.ml │ │ ├── domainstate.ml.c │ │ ├── domainstate.mli.c │ │ ├── dune │ │ ├── identifiable.ml │ │ ├── identifiable.mli │ │ ├── lazy_backtrack.ml │ │ ├── lazy_backtrack.mli │ │ ├── linkdeps.ml │ │ ├── linkdeps.mli │ │ ├── load_path.ml │ │ ├── load_path.mli │ │ ├── local_store.ml │ │ ├── local_store.mli │ │ ├── tbl.ml │ │ ├── tbl.mli │ │ ├── warnings.ml │ │ └── warnings.mli ├── platform │ ├── dune │ ├── os_ipc.ml │ ├── os_ipc_stub.c │ └── platform_misc.c ├── sherlodoc │ ├── .ocamlformat-ignore │ ├── dune │ ├── name_cost.ml │ ├── name_cost.mli │ ├── query.ml │ ├── query.mli │ ├── type_distance.ml │ ├── type_distance.mli │ ├── type_expr.ml │ ├── type_expr.mli │ ├── type_lexer.mll │ ├── type_parsed.ml │ ├── type_parsed.mli │ ├── type_parser.ml │ ├── type_parser.mli │ ├── type_parser.mly │ ├── type_polarity.ml │ └── type_polarity.mli └── utils │ ├── .ocamlformat-ignore │ ├── dune │ ├── file_cache.ml │ ├── file_cache.mli │ ├── file_id.ml │ ├── file_id.mli │ ├── format_doc.ml │ ├── format_doc.mli │ ├── lib_config.ml │ ├── lib_config.mli │ ├── logger.ml │ ├── logger.mli │ ├── marg.ml │ ├── marg.mli │ ├── misc.ml │ ├── misc.mli │ ├── ppxsetup.ml │ ├── ppxsetup.mli │ ├── sexp.ml │ ├── sexp.mli │ ├── stamped_hashtable.ml │ ├── stamped_hashtable.mli │ └── std.ml ├── tests ├── dune ├── merlin-wrapper ├── test-dirs │ ├── .merlin │ ├── alerts.t │ │ ├── lib.mli │ │ ├── main.ml │ │ └── run.t │ ├── completion │ │ ├── application_context.t │ │ │ ├── application_context.ml │ │ │ └── run.t │ │ ├── disambiguation.t │ │ │ ├── constr.ml │ │ │ ├── record.ml │ │ │ └── run.t │ │ ├── dune │ │ ├── expansion.t │ │ │ ├── expansion1.ml │ │ │ ├── expansion2.ml │ │ │ └── run.t │ │ ├── infix.t │ │ │ ├── infix.ml │ │ │ └── run.t │ │ ├── issue-lsp-503.t │ │ ├── issue1575.t │ │ ├── kind.t │ │ │ ├── run.t │ │ │ └── test.ml │ │ └── parenthesize.t │ │ │ ├── parenthesize.ml │ │ │ └── run.t │ ├── config │ │ ├── check │ │ │ ├── check-config.t │ │ │ └── dune │ │ ├── dot-merlin-reader │ │ │ ├── dune │ │ │ ├── erroneous-config.t │ │ │ ├── load-config.t │ │ │ ├── quoting.t │ │ │ └── stdlib-config.t │ │ ├── dune │ │ ├── exclude-query-dir.t │ │ ├── flags │ │ │ ├── dune │ │ │ ├── invalid.t │ │ │ ├── nolabels.t │ │ │ └── unsafe.t │ │ ├── hidden-deps.t │ │ ├── no-dune.t │ │ ├── path-expansion.t │ │ │ └── run.t │ │ ├── symlinks.t │ │ │ ├── real │ │ │ │ └── main.ml │ │ │ └── run.t │ │ ├── unknown_tag.t │ │ └── workdir.t │ │ │ ├── run.t │ │ │ └── src │ │ │ └── main.ml │ ├── construct │ │ ├── c-depth.t │ │ ├── c-errors.t │ │ ├── c-fun.t │ │ ├── c-inline-record-issue1617.t │ │ ├── c-modules.t │ │ │ ├── functor_app.ml │ │ │ ├── module.ml │ │ │ └── run.t │ │ ├── c-objects.t │ │ ├── c-parenthesis.t │ │ ├── c-prefix.t │ │ ├── c-simple.t │ │ ├── dune │ │ └── holes.t │ ├── deprecation.t │ │ ├── foo.mli │ │ ├── run.t │ │ └── x.ml │ ├── destruct │ │ ├── complete.t │ │ ├── create.t │ │ ├── destruct-fun.t │ │ ├── dune │ │ ├── errors.t │ │ ├── from_val.t │ │ ├── issue1300.t │ │ ├── issue1560.t │ │ ├── issue1601.t │ │ ├── issue1661.t │ │ ├── issue1770.t │ │ ├── issue596.t │ │ ├── prefixing.t │ │ ├── record.t │ │ └── refine.t │ ├── document │ │ ├── doc-in-mli.t │ │ ├── dune │ │ ├── external-pattern-comments.t │ │ ├── from-completion-entry.t │ │ ├── issue1513.t │ │ ├── issue1540.t │ │ ├── label-comments.t │ │ ├── module-doc.t │ │ ├── src-documentation.t │ │ │ ├── dune │ │ │ ├── dune-project │ │ │ └── run.t │ │ └── unattached-comment.t │ ├── dune │ ├── enclosing.t │ ├── environment_on_open.t │ │ ├── environment_on_open.ml │ │ └── run.t │ ├── errors │ │ ├── error-in-constrained-env.t │ │ │ ├── run.t │ │ │ └── test.ml │ │ ├── error-node-line-break.t │ │ ├── function-warnings.t │ │ ├── issue1222.t │ │ ├── issue1704-wrong-message.t │ │ ├── issue1753.t │ │ ├── issue1794.t │ │ ├── no-cmi.t │ │ ├── reg503.t │ │ ├── typing-after-parsing.t │ │ │ ├── run.t │ │ │ └── test.ml │ │ ├── undefined-meth.t │ │ └── unused-warnings.t │ ├── function-recovery.t │ ├── hidden-deps │ │ ├── dash-h.t │ │ ├── dune │ │ └── hd-directives.t │ │ │ ├── a │ │ │ ├── a.ml │ │ │ └── a.mli │ │ │ ├── b │ │ │ ├── b.ml │ │ │ └── b.mli │ │ │ ├── c │ │ │ ├── correct.ml │ │ │ └── error.ml │ │ │ └── run.t │ ├── inconsistent-assumptions.t │ ├── inlay-hint │ │ ├── samples.t │ │ └── spec.t │ ├── issue1109.t │ │ ├── issue1109.ml │ │ └── run.t │ ├── issue1322.t │ │ ├── .merlin │ │ ├── foo.ml │ │ ├── nasty.ml │ │ └── run.t │ ├── issue1506.t │ ├── issue1518.t │ ├── issue1558.t │ ├── issue1683-ill-formed-letop.t │ ├── issue1867.t │ ├── issue1900.t │ │ ├── a.ml │ │ ├── dune │ │ ├── dune-project │ │ ├── lib │ │ │ ├── a.ml │ │ │ └── dune │ │ ├── main.ml │ │ └── run.t │ ├── jump-issue1862.t │ ├── locate-type.t │ │ ├── a.ml │ │ ├── b.ml │ │ └── run.t │ ├── locate │ │ ├── ambiguity │ │ │ ├── dune │ │ │ ├── not-in-env.t │ │ │ └── rebinding.t │ │ │ │ ├── rebinding.ml │ │ │ │ └── run.t │ │ ├── context-detection │ │ │ ├── cd-field.t │ │ │ │ ├── field.ml │ │ │ │ └── run.t │ │ │ ├── cd-from_a_pattern.t │ │ │ │ ├── from_a_pattern.ml │ │ │ │ └── run.t │ │ │ ├── cd-label.t │ │ │ │ ├── label.ml │ │ │ │ └── run.t │ │ │ ├── cd-mod_constr.t │ │ │ │ ├── mod_constr.ml │ │ │ │ └── run.t │ │ │ ├── cd-test.t │ │ │ │ ├── run.t │ │ │ │ └── test.ml │ │ │ └── dune │ │ ├── distinguish-files.t │ │ │ ├── bin │ │ │ │ ├── dune │ │ │ │ └── main.ml │ │ │ ├── dune-project │ │ │ ├── lib_a │ │ │ │ ├── different.ml │ │ │ │ ├── dune │ │ │ │ └── same.ml │ │ │ ├── lib_b │ │ │ │ ├── different.ml │ │ │ │ ├── dune │ │ │ │ └── same.ml │ │ │ └── run.t │ │ ├── dune │ │ ├── functors │ │ │ ├── dune │ │ │ ├── f-all_local.t │ │ │ │ ├── all_local.ml │ │ │ │ └── run.t │ │ │ ├── f-from_application.t │ │ │ │ ├── from_application.ml │ │ │ │ └── run.t │ │ │ ├── f-generative.t │ │ │ │ ├── generative.ml │ │ │ │ └── run.t │ │ │ ├── f-included.t │ │ │ │ ├── included.ml │ │ │ │ └── run.t │ │ │ ├── f-missed_shadowing.t │ │ │ │ ├── missed_shadowing.ml │ │ │ │ └── run.t │ │ │ ├── f-nested_applications.t │ │ │ │ ├── nested_applications.ml │ │ │ │ └── run.t │ │ │ └── f-test-ml-mli.t │ │ ├── ill-typed │ │ │ ├── local-open.t │ │ │ ├── locate-cannot-refute.t │ │ │ ├── locate-non-fun.t │ │ │ └── not-a-function.t │ │ ├── in-generated-file.t │ │ │ ├── dune-project │ │ │ ├── main.ml │ │ │ └── run.t │ │ ├── in-implicit-trans-dep.t │ │ │ ├── bin │ │ │ │ ├── dune │ │ │ │ └── main.ml │ │ │ ├── dune-project │ │ │ ├── run.t │ │ │ └── src │ │ │ │ ├── lib1 │ │ │ │ ├── dune │ │ │ │ └── lib1.ml │ │ │ │ └── lib2 │ │ │ │ ├── dune │ │ │ │ └── lib2.ml │ │ ├── includes.t │ │ │ ├── foo.ml │ │ │ ├── run.t │ │ │ └── test.ml │ │ ├── issue1199.t │ │ ├── issue1398.t │ │ │ ├── issue1398.ml │ │ │ └── run.t │ │ ├── issue1424.t │ │ ├── issue1524.t │ │ ├── issue1667.t │ │ ├── issue1842.t │ │ ├── issue1848.t │ │ ├── issue802.t │ │ │ ├── a.ml │ │ │ ├── error.ml │ │ │ ├── mylib__.ml │ │ │ └── run.t │ │ ├── issue845.t │ │ │ ├── local_map.ml │ │ │ ├── local_map.mli │ │ │ └── run.t │ │ ├── issue949.t │ │ ├── l-413-features.t │ │ ├── local-build-scheme.t │ │ ├── local-definitions │ │ │ ├── dune │ │ │ ├── issue798.t │ │ │ │ ├── issue798.ml │ │ │ │ └── run.t │ │ │ └── issue806.t │ │ │ │ ├── issue806.ml │ │ │ │ └── run.t │ │ ├── local-locate.t │ │ ├── locate-constrs.t │ │ ├── looping-substitution.t │ │ │ ├── bar.ml │ │ │ ├── foo.ml │ │ │ ├── run.t │ │ │ └── test.ml │ │ ├── module-aliases.t │ │ │ ├── anothermod.ml │ │ │ ├── anothermod.mli │ │ │ ├── dune │ │ │ ├── dune-project │ │ │ ├── main.ml │ │ │ └── run.t │ │ ├── module-decl-aliases.t │ │ ├── mutually-recursive.t │ │ │ ├── issue973.ml │ │ │ └── run.t │ │ ├── non-local │ │ │ ├── dune │ │ │ ├── ignore-kept-locs.t │ │ │ │ ├── a.ml │ │ │ │ ├── b.ml │ │ │ │ └── run.t │ │ │ └── preference.t │ │ │ │ ├── a.ml │ │ │ │ ├── a.mli │ │ │ │ ├── b.ml │ │ │ │ ├── b.mli │ │ │ │ └── run.t │ │ ├── predef.t │ │ ├── reconstruct-identifier │ │ │ ├── dune │ │ │ ├── newlines.t │ │ │ │ ├── escaped_newline.ml │ │ │ │ ├── newline_in_quotes.ml │ │ │ │ └── run.t │ │ │ └── off_by_one.t │ │ │ │ ├── off_by_one.ml │ │ │ │ └── run.t │ │ ├── record_pun.t │ │ ├── sig-substs.t │ │ │ ├── basic.ml │ │ │ └── run.t │ │ ├── with-holes.t │ │ │ └── run.t │ │ ├── without-implem.t │ │ └── without-sig.t │ ├── misc │ │ ├── external-arity.t │ │ └── load_path.t │ ├── motion │ │ ├── jump.t │ │ ├── jump_match.t │ │ └── phrase.t │ ├── no-escape.t │ │ ├── foo.cmi │ │ ├── run.t │ │ ├── test_open.ml │ │ └── test_use.ml │ ├── occurrences │ │ ├── basic.t │ │ │ ├── basic.ml │ │ │ └── run.t │ │ ├── dune │ │ ├── ext-variant.t │ │ ├── from-origin.t │ │ ├── issue1398.t │ │ │ ├── issue1398.ml │ │ │ └── run.t │ │ ├── issue1404.t │ │ ├── issue1410.t │ │ ├── issue827.t │ │ │ ├── issue827.ml │ │ │ └── run.t │ │ ├── lid-locs.t │ │ ├── mod-in-path-2.t │ │ ├── mod-in-path-3.t │ │ ├── mod-in-path.t │ │ ├── no-def-mli-only.t │ │ ├── occ-types.t │ │ ├── occ-with-ppx.t │ │ ├── pattern.t │ │ └── project-wide │ │ │ ├── dune │ │ │ ├── for-renaming │ │ │ ├── r-modules-and-types.t │ │ │ └── r-with-functors.t │ │ │ │ ├── dune │ │ │ │ ├── dune-project │ │ │ │ ├── func.ml │ │ │ │ ├── func.mli │ │ │ │ ├── main.ml │ │ │ │ └── run.t │ │ │ ├── mli-vs-ml.t │ │ │ ├── prefix.t │ │ │ ├── a.ml │ │ │ ├── b.ml │ │ │ └── run.t │ │ │ ├── pwo-basic.t │ │ │ ├── pwo-canonicalize.t │ │ │ ├── pwo-ml-gen.t │ │ │ ├── pwo-relative.t │ │ │ ├── stale-index.t │ │ │ └── union.t │ ├── outline-recovery.t │ ├── outline.t │ │ ├── foo.ml │ │ ├── foo.mli │ │ ├── path.ml │ │ ├── path.mli │ │ └── run.t │ ├── polarity-search.t │ ├── pp │ │ ├── dot-pp-dot-ml-dune.t │ │ ├── dot-pp-dot-ml.t │ │ ├── dune │ │ └── simple-pp.t │ ├── recovery.t │ ├── refactor-open │ │ ├── functor-app.t │ │ │ ├── run.t │ │ │ └── test.ml │ │ ├── qualify.t │ │ ├── qualify_short_paths.t │ │ ├── record_field.t │ │ └── unqualify.t │ ├── search │ │ ├── dune │ │ ├── issue1113.t │ │ ├── polarity-search-comparison-to-search-by-type.t │ │ ├── search-by-type-comparison-to-polarity-search.t │ │ └── search-by-type.t │ │ │ ├── context.ml │ │ │ └── run.t │ ├── server-tests │ │ ├── cache-time.t │ │ ├── chdir_to_root.t │ │ ├── dune │ │ ├── incremental-index.t │ │ ├── locate-state │ │ │ └── reset-file-switching.t │ │ ├── pwo-uid-stability.t │ │ ├── stable-uids.t │ │ ├── typer-cache │ │ │ ├── current-level.t │ │ │ │ └── run.t │ │ │ ├── dune │ │ │ ├── load_path.t │ │ │ │ ├── run.t │ │ │ │ ├── sub │ │ │ │ │ └── dep.ml │ │ │ │ └── test.ml │ │ │ ├── stamps.t │ │ │ │ └── run.t │ │ │ └── sub.t │ │ │ │ ├── run.t │ │ │ │ └── test.ml │ │ └── warnings │ │ │ └── backtrack.t │ ├── short-paths │ │ ├── double-trouble.t │ │ └── short-paths.t │ │ │ ├── dep.mli │ │ │ ├── run.t │ │ │ └── test.ml │ ├── signature-help │ │ ├── issue1927.t │ │ ├── sh-mix.t │ │ └── signature-help.t │ ├── sp-normalization.t │ ├── string-loc.t │ ├── syntax-document │ │ └── language-extensions.t │ │ │ └── run.t │ ├── type-enclosing │ │ ├── 503-effects.t │ │ ├── constructors_and_paths.t │ │ │ ├── cons.ml │ │ │ └── run.t │ │ ├── gadt_wrong.t │ │ ├── generic-types.t │ │ ├── github1003.t │ │ │ ├── issue1003.ml │ │ │ └── run.t │ │ ├── hole.t │ │ ├── inside-tydecl.t │ │ ├── issue1116.t │ │ │ ├── issue1116.ml │ │ │ └── run.t │ │ ├── issue1226.t │ │ ├── issue1278.t │ │ ├── issue1335.t │ │ ├── issue1477.t │ │ ├── issue1564.t │ │ ├── issue1607.t │ │ ├── issue1755.t │ │ ├── issue864.t │ │ │ ├── issue864.ml │ │ │ └── run.t │ │ ├── issueLSP444.t │ │ ├── issueLSP695.t │ │ │ ├── main.ml │ │ │ └── run.t │ │ ├── let.t │ │ │ ├── let.ml │ │ │ └── run.t │ │ ├── letop.t │ │ │ ├── letop.ml │ │ │ └── run.t │ │ ├── letop2.t │ │ │ ├── letop.ml │ │ │ └── run.t │ │ ├── merlin-hide.t │ │ ├── mod-alias.t │ │ │ ├── alias.ml │ │ │ └── run.t │ │ ├── mod-not-in-env.t │ │ │ ├── not-in-env.ml │ │ │ └── run.t │ │ ├── mod-type.t │ │ │ ├── module_type.mli │ │ │ └── run.t │ │ ├── need-parens.t │ │ ├── objects.t │ │ │ ├── run.t │ │ │ └── test.ml │ │ ├── record.t │ │ │ ├── record.ml │ │ │ └── run.t │ │ ├── te-413-features.t │ │ ├── te-modules.t │ │ ├── type-alias.t │ │ ├── type-fun-recovery.t │ │ ├── types.t │ │ │ ├── run.t │ │ │ └── types.ml │ │ ├── underscore-ids.t │ │ ├── variants.t │ │ │ ├── run.t │ │ │ └── variants.ml │ │ └── verbosity_smart.t │ │ │ ├── run.t │ │ │ └── test.ml │ ├── type-expr.t │ │ ├── run.t │ │ └── test.ml │ ├── typing-recovery.t │ ├── with-cmi.t │ └── with-ppx │ │ ├── dune │ │ ├── expand_node.t │ │ ├── c_ppx │ │ │ ├── c_ppx.ml │ │ │ └── dune │ │ ├── rewriter │ │ │ ├── dune │ │ │ └── my_ppx.ml │ │ └── run.t │ │ ├── issue1647-cache-invalidation.t │ │ ├── issue1660-deriving-compare.t │ │ ├── issue1671-string.t │ │ ├── parsetree-cache.t │ │ ├── dune │ │ ├── dune-project │ │ └── run.t │ │ └── typed-holes.t │ │ ├── dune │ │ ├── dune-project │ │ ├── rewriter │ │ ├── dune │ │ └── my_ppx.ml │ │ └── run.t └── test-units │ └── sherldoc │ ├── dune │ ├── name_cost_test.ml │ ├── name_cost_test.mli │ ├── query_test.ml │ ├── query_test.mli │ ├── sherlodoc_test.ml │ ├── type_distance_test.ml │ ├── type_distance_test.mli │ ├── type_expr_test.ml │ └── type_expr_test.mli ├── upstream ├── gen_patch.sh ├── ocaml_414 │ ├── base-rev.txt │ ├── file_formats │ │ ├── cmi_format.ml │ │ ├── cmi_format.mli │ │ ├── cmo_format.mli │ │ ├── cmt_format.ml │ │ ├── cmt_format.mli │ │ ├── cmx_format.mli │ │ ├── cmxs_format.mli │ │ ├── linear_format.ml │ │ └── linear_format.mli │ ├── parsing │ │ ├── ast_helper.ml │ │ ├── ast_helper.mli │ │ ├── ast_invariants.ml │ │ ├── ast_invariants.mli │ │ ├── ast_iterator.ml │ │ ├── ast_iterator.mli │ │ ├── ast_mapper.ml │ │ ├── ast_mapper.mli │ │ ├── asttypes.mli │ │ ├── attr_helper.ml │ │ ├── attr_helper.mli │ │ ├── builtin_attributes.ml │ │ ├── builtin_attributes.mli │ │ ├── depend.ml │ │ ├── depend.mli │ │ ├── docstrings.ml │ │ ├── docstrings.mli │ │ ├── lexer.mli │ │ ├── lexer.mll │ │ ├── location.ml │ │ ├── location.mli │ │ ├── longident.ml │ │ ├── longident.mli │ │ ├── parse.ml │ │ ├── parse.mli │ │ ├── parser.mly │ │ ├── parsetree.mli │ │ ├── pprintast.ml │ │ ├── pprintast.mli │ │ ├── printast.ml │ │ ├── printast.mli │ │ ├── syntaxerr.ml │ │ └── syntaxerr.mli │ ├── typing │ │ ├── annot.mli │ │ ├── btype.ml │ │ ├── btype.mli │ │ ├── cmt2annot.ml │ │ ├── ctype.ml │ │ ├── ctype.mli │ │ ├── datarepr.ml │ │ ├── datarepr.mli │ │ ├── env.ml │ │ ├── env.mli │ │ ├── envaux.ml │ │ ├── envaux.mli │ │ ├── errortrace.ml │ │ ├── errortrace.mli │ │ ├── ident.ml │ │ ├── ident.mli │ │ ├── includeclass.ml │ │ ├── includeclass.mli │ │ ├── includecore.ml │ │ ├── includecore.mli │ │ ├── includemod.ml │ │ ├── includemod.mli │ │ ├── includemod_errorprinter.ml │ │ ├── includemod_errorprinter.mli │ │ ├── mtype.ml │ │ ├── mtype.mli │ │ ├── oprint.ml │ │ ├── oprint.mli │ │ ├── outcometree.mli │ │ ├── parmatch.ml │ │ ├── parmatch.mli │ │ ├── path.ml │ │ ├── path.mli │ │ ├── patterns.ml │ │ ├── patterns.mli │ │ ├── persistent_env.ml │ │ ├── persistent_env.mli │ │ ├── predef.ml │ │ ├── predef.mli │ │ ├── primitive.ml │ │ ├── primitive.mli │ │ ├── printpat.ml │ │ ├── printpat.mli │ │ ├── printtyp.ml │ │ ├── printtyp.mli │ │ ├── printtyped.ml │ │ ├── printtyped.mli │ │ ├── rec_check.ml │ │ ├── rec_check.mli │ │ ├── shape.ml │ │ ├── shape.mli │ │ ├── signature_group.ml │ │ ├── signature_group.mli │ │ ├── stypes.ml │ │ ├── stypes.mli │ │ ├── subst.ml │ │ ├── subst.mli │ │ ├── tast_iterator.ml │ │ ├── tast_iterator.mli │ │ ├── tast_mapper.ml │ │ ├── tast_mapper.mli │ │ ├── type_immediacy.ml │ │ ├── type_immediacy.mli │ │ ├── typeclass.ml │ │ ├── typeclass.mli │ │ ├── typecore.ml │ │ ├── typecore.mli │ │ ├── typedecl.ml │ │ ├── typedecl.mli │ │ ├── typedecl_immediacy.ml │ │ ├── typedecl_immediacy.mli │ │ ├── typedecl_properties.ml │ │ ├── typedecl_properties.mli │ │ ├── typedecl_separability.ml │ │ ├── typedecl_separability.mli │ │ ├── typedecl_unboxed.ml │ │ ├── typedecl_unboxed.mli │ │ ├── typedecl_variance.ml │ │ ├── typedecl_variance.mli │ │ ├── typedtree.ml │ │ ├── typedtree.mli │ │ ├── typemod.ml │ │ ├── typemod.mli │ │ ├── typeopt.ml │ │ ├── typeopt.mli │ │ ├── types.ml │ │ ├── types.mli │ │ ├── typetexp.ml │ │ ├── typetexp.mli │ │ ├── untypeast.ml │ │ └── untypeast.mli │ └── utils │ │ ├── Makefile │ │ ├── arg_helper.ml │ │ ├── arg_helper.mli │ │ ├── binutils.ml │ │ ├── binutils.mli │ │ ├── build_path_prefix_map.ml │ │ ├── build_path_prefix_map.mli │ │ ├── ccomp.ml │ │ ├── ccomp.mli │ │ ├── clflags.ml │ │ ├── clflags.mli │ │ ├── config.mli │ │ ├── config.mlp │ │ ├── consistbl.ml │ │ ├── consistbl.mli │ │ ├── diffing.ml │ │ ├── diffing.mli │ │ ├── diffing_with_keys.ml │ │ ├── diffing_with_keys.mli │ │ ├── domainstate.ml.c │ │ ├── domainstate.mli.c │ │ ├── identifiable.ml │ │ ├── identifiable.mli │ │ ├── int_replace_polymorphic_compare.ml │ │ ├── int_replace_polymorphic_compare.mli │ │ ├── lazy_backtrack.ml │ │ ├── lazy_backtrack.mli │ │ ├── load_path.ml │ │ ├── load_path.mli │ │ ├── local_store.ml │ │ ├── local_store.mli │ │ ├── misc.ml │ │ ├── misc.mli │ │ ├── numbers.ml │ │ ├── numbers.mli │ │ ├── profile.ml │ │ ├── profile.mli │ │ ├── strongly_connected_components.ml │ │ ├── strongly_connected_components.mli │ │ ├── targetint.ml │ │ ├── targetint.mli │ │ ├── terminfo.ml │ │ ├── terminfo.mli │ │ ├── warnings.ml │ │ └── warnings.mli ├── ocaml_500 │ ├── base-rev.txt │ ├── file_formats │ │ ├── cmi_format.ml │ │ ├── cmi_format.mli │ │ ├── cmo_format.mli │ │ ├── cmt_format.ml │ │ ├── cmt_format.mli │ │ ├── cmx_format.mli │ │ ├── cmxs_format.mli │ │ ├── linear_format.ml │ │ └── linear_format.mli │ ├── parsing │ │ ├── CONFLICTS.md │ │ ├── ast_helper.ml │ │ ├── ast_helper.mli │ │ ├── ast_invariants.ml │ │ ├── ast_invariants.mli │ │ ├── ast_iterator.ml │ │ ├── ast_iterator.mli │ │ ├── ast_mapper.ml │ │ ├── ast_mapper.mli │ │ ├── asttypes.mli │ │ ├── attr_helper.ml │ │ ├── attr_helper.mli │ │ ├── builtin_attributes.ml │ │ ├── builtin_attributes.mli │ │ ├── depend.ml │ │ ├── depend.mli │ │ ├── docstrings.ml │ │ ├── docstrings.mli │ │ ├── lexer.mli │ │ ├── lexer.mll │ │ ├── location.ml │ │ ├── location.mli │ │ ├── longident.ml │ │ ├── longident.mli │ │ ├── parse.ml │ │ ├── parse.mli │ │ ├── parser.mly │ │ ├── parsetree.mli │ │ ├── pprintast.ml │ │ ├── pprintast.mli │ │ ├── printast.ml │ │ ├── printast.mli │ │ ├── syntaxerr.ml │ │ └── syntaxerr.mli │ ├── typing │ │ ├── annot.mli │ │ ├── btype.ml │ │ ├── btype.mli │ │ ├── cmt2annot.ml │ │ ├── ctype.ml │ │ ├── ctype.mli │ │ ├── datarepr.ml │ │ ├── datarepr.mli │ │ ├── env.ml │ │ ├── env.mli │ │ ├── envaux.ml │ │ ├── envaux.mli │ │ ├── errortrace.ml │ │ ├── errortrace.mli │ │ ├── ident.ml │ │ ├── ident.mli │ │ ├── includeclass.ml │ │ ├── includeclass.mli │ │ ├── includecore.ml │ │ ├── includecore.mli │ │ ├── includemod.ml │ │ ├── includemod.mli │ │ ├── includemod_errorprinter.ml │ │ ├── includemod_errorprinter.mli │ │ ├── mtype.ml │ │ ├── mtype.mli │ │ ├── oprint.ml │ │ ├── oprint.mli │ │ ├── outcometree.mli │ │ ├── parmatch.ml │ │ ├── parmatch.mli │ │ ├── path.ml │ │ ├── path.mli │ │ ├── patterns.ml │ │ ├── patterns.mli │ │ ├── persistent_env.ml │ │ ├── persistent_env.mli │ │ ├── predef.ml │ │ ├── predef.mli │ │ ├── primitive.ml │ │ ├── primitive.mli │ │ ├── printpat.ml │ │ ├── printpat.mli │ │ ├── printtyp.ml │ │ ├── printtyp.mli │ │ ├── printtyped.ml │ │ ├── printtyped.mli │ │ ├── rec_check.ml │ │ ├── rec_check.mli │ │ ├── shape.ml │ │ ├── shape.mli │ │ ├── signature_group.ml │ │ ├── signature_group.mli │ │ ├── stypes.ml │ │ ├── stypes.mli │ │ ├── subst.ml │ │ ├── subst.mli │ │ ├── tast_iterator.ml │ │ ├── tast_iterator.mli │ │ ├── tast_mapper.ml │ │ ├── tast_mapper.mli │ │ ├── type_immediacy.ml │ │ ├── type_immediacy.mli │ │ ├── typeclass.ml │ │ ├── typeclass.mli │ │ ├── typecore.ml │ │ ├── typecore.mli │ │ ├── typedecl.ml │ │ ├── typedecl.mli │ │ ├── typedecl_immediacy.ml │ │ ├── typedecl_immediacy.mli │ │ ├── typedecl_properties.ml │ │ ├── typedecl_properties.mli │ │ ├── typedecl_separability.ml │ │ ├── typedecl_separability.mli │ │ ├── typedecl_unboxed.ml │ │ ├── typedecl_unboxed.mli │ │ ├── typedecl_variance.ml │ │ ├── typedecl_variance.mli │ │ ├── typedtree.ml │ │ ├── typedtree.mli │ │ ├── typemod.ml │ │ ├── typemod.mli │ │ ├── typeopt.ml │ │ ├── typeopt.mli │ │ ├── types.ml │ │ ├── types.mli │ │ ├── typetexp.ml │ │ ├── typetexp.mli │ │ ├── untypeast.ml │ │ └── untypeast.mli │ └── utils │ │ ├── arg_helper.ml │ │ ├── arg_helper.mli │ │ ├── binutils.ml │ │ ├── binutils.mli │ │ ├── build_path_prefix_map.ml │ │ ├── build_path_prefix_map.mli │ │ ├── ccomp.ml │ │ ├── ccomp.mli │ │ ├── clflags.ml │ │ ├── clflags.mli │ │ ├── config.common.ml │ │ ├── config.fixed.ml │ │ ├── config.mli │ │ ├── config.mlp │ │ ├── consistbl.ml │ │ ├── consistbl.mli │ │ ├── diffing.ml │ │ ├── diffing.mli │ │ ├── diffing_with_keys.ml │ │ ├── diffing_with_keys.mli │ │ ├── domainstate.ml.c │ │ ├── domainstate.mli.c │ │ ├── identifiable.ml │ │ ├── identifiable.mli │ │ ├── int_replace_polymorphic_compare.ml │ │ ├── int_replace_polymorphic_compare.mli │ │ ├── lazy_backtrack.ml │ │ ├── lazy_backtrack.mli │ │ ├── load_path.ml │ │ ├── load_path.mli │ │ ├── local_store.ml │ │ ├── local_store.mli │ │ ├── misc.ml │ │ ├── misc.mli │ │ ├── numbers.ml │ │ ├── numbers.mli │ │ ├── profile.ml │ │ ├── profile.mli │ │ ├── strongly_connected_components.ml │ │ ├── strongly_connected_components.mli │ │ ├── targetint.ml │ │ ├── targetint.mli │ │ ├── terminfo.ml │ │ ├── terminfo.mli │ │ ├── warnings.ml │ │ └── warnings.mli ├── ocaml_501 │ ├── base-rev.txt │ ├── file_formats │ │ ├── cmi_format.ml │ │ ├── cmi_format.mli │ │ ├── cmt_format.ml │ │ └── cmt_format.mli │ ├── parsing │ │ ├── CONFLICTS.md │ │ ├── ast_helper.ml │ │ ├── ast_helper.mli │ │ ├── ast_invariants.ml │ │ ├── ast_invariants.mli │ │ ├── ast_iterator.ml │ │ ├── ast_iterator.mli │ │ ├── ast_mapper.ml │ │ ├── ast_mapper.mli │ │ ├── asttypes.mli │ │ ├── attr_helper.ml │ │ ├── attr_helper.mli │ │ ├── builtin_attributes.ml │ │ ├── builtin_attributes.mli │ │ ├── depend.ml │ │ ├── depend.mli │ │ ├── docstrings.ml │ │ ├── docstrings.mli │ │ ├── lexer.mli │ │ ├── lexer.mll │ │ ├── location.ml │ │ ├── location.mli │ │ ├── longident.ml │ │ ├── longident.mli │ │ ├── parse.ml │ │ ├── parse.mli │ │ ├── parser.mly │ │ ├── parsetree.mli │ │ ├── pprintast.ml │ │ ├── pprintast.mli │ │ ├── printast.ml │ │ ├── printast.mli │ │ ├── syntaxerr.ml │ │ └── syntaxerr.mli │ ├── typing │ │ ├── annot.mli │ │ ├── btype.ml │ │ ├── btype.mli │ │ ├── cmt2annot.ml │ │ ├── cmt2annot.mli │ │ ├── ctype.ml │ │ ├── ctype.mli │ │ ├── datarepr.ml │ │ ├── datarepr.mli │ │ ├── env.ml │ │ ├── env.mli │ │ ├── envaux.ml │ │ ├── envaux.mli │ │ ├── errortrace.ml │ │ ├── errortrace.mli │ │ ├── ident.ml │ │ ├── ident.mli │ │ ├── includeclass.ml │ │ ├── includeclass.mli │ │ ├── includecore.ml │ │ ├── includecore.mli │ │ ├── includemod.ml │ │ ├── includemod.mli │ │ ├── includemod_errorprinter.ml │ │ ├── includemod_errorprinter.mli │ │ ├── mtype.ml │ │ ├── mtype.mli │ │ ├── oprint.ml │ │ ├── oprint.mli │ │ ├── outcometree.mli │ │ ├── parmatch.ml │ │ ├── parmatch.mli │ │ ├── path.ml │ │ ├── path.mli │ │ ├── patterns.ml │ │ ├── patterns.mli │ │ ├── persistent_env.ml │ │ ├── persistent_env.mli │ │ ├── predef.ml │ │ ├── predef.mli │ │ ├── primitive.ml │ │ ├── primitive.mli │ │ ├── printpat.ml │ │ ├── printpat.mli │ │ ├── printtyp.ml │ │ ├── printtyp.mli │ │ ├── printtyped.ml │ │ ├── printtyped.mli │ │ ├── rec_check.ml │ │ ├── rec_check.mli │ │ ├── shape.ml │ │ ├── shape.mli │ │ ├── signature_group.ml │ │ ├── signature_group.mli │ │ ├── stypes.ml │ │ ├── stypes.mli │ │ ├── subst.ml │ │ ├── subst.mli │ │ ├── tast_iterator.ml │ │ ├── tast_iterator.mli │ │ ├── tast_mapper.ml │ │ ├── tast_mapper.mli │ │ ├── type_immediacy.ml │ │ ├── type_immediacy.mli │ │ ├── typeclass.ml │ │ ├── typeclass.mli │ │ ├── typecore.ml │ │ ├── typecore.mli │ │ ├── typedecl.ml │ │ ├── typedecl.mli │ │ ├── typedecl_immediacy.ml │ │ ├── typedecl_immediacy.mli │ │ ├── typedecl_properties.ml │ │ ├── typedecl_properties.mli │ │ ├── typedecl_separability.ml │ │ ├── typedecl_separability.mli │ │ ├── typedecl_unboxed.ml │ │ ├── typedecl_unboxed.mli │ │ ├── typedecl_variance.ml │ │ ├── typedecl_variance.mli │ │ ├── typedtree.ml │ │ ├── typedtree.mli │ │ ├── typemod.ml │ │ ├── typemod.mli │ │ ├── typeopt.ml │ │ ├── typeopt.mli │ │ ├── types.ml │ │ ├── types.mli │ │ ├── typetexp.ml │ │ ├── typetexp.mli │ │ ├── untypeast.ml │ │ └── untypeast.mli │ └── utils │ │ ├── arg_helper.ml │ │ ├── arg_helper.mli │ │ ├── binutils.ml │ │ ├── binutils.mli │ │ ├── build_path_prefix_map.ml │ │ ├── build_path_prefix_map.mli │ │ ├── ccomp.ml │ │ ├── ccomp.mli │ │ ├── clflags.ml │ │ ├── clflags.mli │ │ ├── config.common.ml │ │ ├── config.fixed.ml │ │ ├── config.ml │ │ ├── config.mli │ │ ├── consistbl.ml │ │ ├── consistbl.mli │ │ ├── diffing.ml │ │ ├── diffing.mli │ │ ├── diffing_with_keys.ml │ │ ├── diffing_with_keys.mli │ │ ├── domainstate.ml.c │ │ ├── domainstate.mli.c │ │ ├── identifiable.ml │ │ ├── identifiable.mli │ │ ├── int_replace_polymorphic_compare.ml │ │ ├── int_replace_polymorphic_compare.mli │ │ ├── lazy_backtrack.ml │ │ ├── lazy_backtrack.mli │ │ ├── load_path.ml │ │ ├── load_path.mli │ │ ├── local_store.ml │ │ ├── local_store.mli │ │ ├── misc.ml │ │ ├── misc.mli │ │ ├── numbers.ml │ │ ├── numbers.mli │ │ ├── profile.ml │ │ ├── profile.mli │ │ ├── strongly_connected_components.ml │ │ ├── strongly_connected_components.mli │ │ ├── targetint.ml │ │ ├── targetint.mli │ │ ├── terminfo.ml │ │ ├── terminfo.mli │ │ ├── warnings.ml │ │ └── warnings.mli ├── ocaml_502 │ ├── base-rev.txt │ ├── file_formats │ │ ├── cmi_format.ml │ │ ├── cmi_format.mli │ │ ├── cmt_format.ml │ │ └── cmt_format.mli │ ├── parsing │ │ ├── ast_helper.ml │ │ ├── ast_helper.mli │ │ ├── ast_invariants.ml │ │ ├── ast_invariants.mli │ │ ├── ast_iterator.ml │ │ ├── ast_iterator.mli │ │ ├── ast_mapper.ml │ │ ├── ast_mapper.mli │ │ ├── asttypes.mli │ │ ├── attr_helper.ml │ │ ├── attr_helper.mli │ │ ├── builtin_attributes.ml │ │ ├── builtin_attributes.mli │ │ ├── depend.ml │ │ ├── depend.mli │ │ ├── docstrings.ml │ │ ├── docstrings.mli │ │ ├── lexer.mli │ │ ├── lexer.mll │ │ ├── location.ml │ │ ├── location.mli │ │ ├── longident.ml │ │ ├── longident.mli │ │ ├── parse.ml │ │ ├── parse.mli │ │ ├── parser.mly │ │ ├── parsetree.mli │ │ ├── pprintast.ml │ │ ├── pprintast.mli │ │ ├── printast.ml │ │ ├── printast.mli │ │ ├── syntaxerr.ml │ │ ├── syntaxerr.mli │ │ ├── unit_info.ml │ │ └── unit_info.mli │ ├── typing │ │ ├── annot.mli │ │ ├── btype.ml │ │ ├── btype.mli │ │ ├── cmt2annot.ml │ │ ├── cmt2annot.mli │ │ ├── ctype.ml │ │ ├── ctype.mli │ │ ├── datarepr.ml │ │ ├── datarepr.mli │ │ ├── env.ml │ │ ├── env.mli │ │ ├── envaux.ml │ │ ├── envaux.mli │ │ ├── errortrace.ml │ │ ├── errortrace.mli │ │ ├── ident.ml │ │ ├── ident.mli │ │ ├── includeclass.ml │ │ ├── includeclass.mli │ │ ├── includecore.ml │ │ ├── includecore.mli │ │ ├── includemod.ml │ │ ├── includemod.mli │ │ ├── includemod_errorprinter.ml │ │ ├── includemod_errorprinter.mli │ │ ├── mtype.ml │ │ ├── mtype.mli │ │ ├── oprint.ml │ │ ├── oprint.mli │ │ ├── outcometree.mli │ │ ├── parmatch.ml │ │ ├── parmatch.mli │ │ ├── path.ml │ │ ├── path.mli │ │ ├── patterns.ml │ │ ├── patterns.mli │ │ ├── persistent_env.ml │ │ ├── persistent_env.mli │ │ ├── predef.ml │ │ ├── predef.mli │ │ ├── primitive.ml │ │ ├── primitive.mli │ │ ├── printpat.ml │ │ ├── printpat.mli │ │ ├── printtyp.ml │ │ ├── printtyp.mli │ │ ├── printtyped.ml │ │ ├── printtyped.mli │ │ ├── shape.ml │ │ ├── shape.mli │ │ ├── shape_reduce.ml │ │ ├── shape_reduce.mli │ │ ├── signature_group.ml │ │ ├── signature_group.mli │ │ ├── stypes.ml │ │ ├── stypes.mli │ │ ├── subst.ml │ │ ├── subst.mli │ │ ├── tast_iterator.ml │ │ ├── tast_iterator.mli │ │ ├── tast_mapper.ml │ │ ├── tast_mapper.mli │ │ ├── type_immediacy.ml │ │ ├── type_immediacy.mli │ │ ├── typeclass.ml │ │ ├── typeclass.mli │ │ ├── typecore.ml │ │ ├── typecore.mli │ │ ├── typedecl.ml │ │ ├── typedecl.mli │ │ ├── typedecl_immediacy.ml │ │ ├── typedecl_immediacy.mli │ │ ├── typedecl_properties.ml │ │ ├── typedecl_properties.mli │ │ ├── typedecl_separability.ml │ │ ├── typedecl_separability.mli │ │ ├── typedecl_unboxed.ml │ │ ├── typedecl_unboxed.mli │ │ ├── typedecl_variance.ml │ │ ├── typedecl_variance.mli │ │ ├── typedtree.ml │ │ ├── typedtree.mli │ │ ├── typemod.ml │ │ ├── typemod.mli │ │ ├── typeopt.ml │ │ ├── typeopt.mli │ │ ├── types.ml │ │ ├── types.mli │ │ ├── typetexp.ml │ │ ├── typetexp.mli │ │ ├── untypeast.ml │ │ ├── untypeast.mli │ │ ├── value_rec_check.ml │ │ ├── value_rec_check.mli │ │ └── value_rec_types.mli │ └── utils │ │ ├── arg_helper.ml │ │ ├── arg_helper.mli │ │ ├── binutils.ml │ │ ├── binutils.mli │ │ ├── build_path_prefix_map.ml │ │ ├── build_path_prefix_map.mli │ │ ├── ccomp.ml │ │ ├── ccomp.mli │ │ ├── clflags.ml │ │ ├── clflags.mli │ │ ├── config.fixed.ml │ │ ├── config.mli │ │ ├── consistbl.ml │ │ ├── consistbl.mli │ │ ├── diffing.ml │ │ ├── diffing.mli │ │ ├── diffing_with_keys.ml │ │ ├── diffing_with_keys.mli │ │ ├── identifiable.ml │ │ ├── identifiable.mli │ │ ├── int_replace_polymorphic_compare.ml │ │ ├── int_replace_polymorphic_compare.mli │ │ ├── lazy_backtrack.ml │ │ ├── lazy_backtrack.mli │ │ ├── load_path.ml │ │ ├── load_path.mli │ │ ├── local_store.ml │ │ ├── local_store.mli │ │ ├── misc.ml │ │ ├── misc.mli │ │ ├── numbers.ml │ │ ├── numbers.mli │ │ ├── profile.ml │ │ ├── profile.mli │ │ ├── strongly_connected_components.ml │ │ ├── strongly_connected_components.mli │ │ ├── targetint.ml │ │ ├── targetint.mli │ │ ├── terminfo.ml │ │ ├── terminfo.mli │ │ ├── warnings.ml │ │ └── warnings.mli └── ocaml_503 │ ├── base-rev.txt │ ├── file_formats │ ├── cmi_format.ml │ ├── cmi_format.mli │ ├── cmt_format.ml │ └── cmt_format.mli │ ├── parsing │ ├── ast_helper.ml │ ├── ast_helper.mli │ ├── ast_invariants.ml │ ├── ast_invariants.mli │ ├── ast_iterator.ml │ ├── ast_iterator.mli │ ├── ast_mapper.ml │ ├── ast_mapper.mli │ ├── asttypes.ml │ ├── asttypes.mli │ ├── attr_helper.ml │ ├── attr_helper.mli │ ├── builtin_attributes.ml │ ├── builtin_attributes.mli │ ├── depend.ml │ ├── depend.mli │ ├── docstrings.ml │ ├── docstrings.mli │ ├── lexer.mli │ ├── lexer.mll │ ├── location.ml │ ├── location.mli │ ├── longident.ml │ ├── longident.mli │ ├── parse.ml │ ├── parse.mli │ ├── parser.mly │ ├── parsetree.mli │ ├── pprintast.ml │ ├── pprintast.mli │ ├── printast.ml │ ├── printast.mli │ ├── syntaxerr.ml │ ├── syntaxerr.mli │ ├── unit_info.ml │ └── unit_info.mli │ ├── typing │ ├── annot.mli │ ├── btype.ml │ ├── btype.mli │ ├── cmt2annot.ml │ ├── cmt2annot.mli │ ├── ctype.ml │ ├── ctype.mli │ ├── datarepr.ml │ ├── datarepr.mli │ ├── env.ml │ ├── env.mli │ ├── envaux.ml │ ├── envaux.mli │ ├── errortrace.ml │ ├── errortrace.mli │ ├── errortrace_report.ml │ ├── errortrace_report.mli │ ├── gprinttyp.ml │ ├── gprinttyp.mli │ ├── ident.ml │ ├── ident.mli │ ├── includeclass.ml │ ├── includeclass.mli │ ├── includecore.ml │ ├── includecore.mli │ ├── includemod.ml │ ├── includemod.mli │ ├── includemod_errorprinter.ml │ ├── includemod_errorprinter.mli │ ├── mtype.ml │ ├── mtype.mli │ ├── oprint.ml │ ├── oprint.mli │ ├── out_type.ml │ ├── out_type.mli │ ├── outcometree.mli │ ├── parmatch.ml │ ├── parmatch.mli │ ├── path.ml │ ├── path.mli │ ├── patterns.ml │ ├── patterns.mli │ ├── persistent_env.ml │ ├── persistent_env.mli │ ├── predef.ml │ ├── predef.mli │ ├── primitive.ml │ ├── primitive.mli │ ├── printpat.ml │ ├── printpat.mli │ ├── printtyp.ml │ ├── printtyp.mli │ ├── printtyped.ml │ ├── printtyped.mli │ ├── rawprinttyp.ml │ ├── rawprinttyp.mli │ ├── shape.ml │ ├── shape.mli │ ├── shape_reduce.ml │ ├── shape_reduce.mli │ ├── signature_group.ml │ ├── signature_group.mli │ ├── stypes.ml │ ├── stypes.mli │ ├── subst.ml │ ├── subst.mli │ ├── tast_iterator.ml │ ├── tast_iterator.mli │ ├── tast_mapper.ml │ ├── tast_mapper.mli │ ├── type_immediacy.ml │ ├── type_immediacy.mli │ ├── typeclass.ml │ ├── typeclass.mli │ ├── typecore.ml │ ├── typecore.mli │ ├── typedecl.ml │ ├── typedecl.mli │ ├── typedecl_immediacy.ml │ ├── typedecl_immediacy.mli │ ├── typedecl_properties.ml │ ├── typedecl_properties.mli │ ├── typedecl_separability.ml │ ├── typedecl_separability.mli │ ├── typedecl_unboxed.ml │ ├── typedecl_unboxed.mli │ ├── typedecl_variance.ml │ ├── typedecl_variance.mli │ ├── typedtree.ml │ ├── typedtree.mli │ ├── typemod.ml │ ├── typemod.mli │ ├── typeopt.ml │ ├── typeopt.mli │ ├── types.ml │ ├── types.mli │ ├── typetexp.ml │ ├── typetexp.mli │ ├── untypeast.ml │ ├── untypeast.mli │ ├── value_rec_check.ml │ ├── value_rec_check.mli │ └── value_rec_types.mli │ └── utils │ ├── arg_helper.ml │ ├── arg_helper.mli │ ├── binutils.ml │ ├── binutils.mli │ ├── build_path_prefix_map.ml │ ├── build_path_prefix_map.mli │ ├── ccomp.ml │ ├── ccomp.mli │ ├── clflags.ml │ ├── clflags.mli │ ├── compression.ml │ ├── compression.mli │ ├── config.common.ml.in │ ├── config.fixed.ml │ ├── config.generated.ml.in │ ├── config.mli │ ├── consistbl.ml │ ├── consistbl.mli │ ├── diffing.ml │ ├── diffing.mli │ ├── diffing_with_keys.ml │ ├── diffing_with_keys.mli │ ├── domainstate.ml.c │ ├── domainstate.mli.c │ ├── format_doc.ml │ ├── format_doc.mli │ ├── identifiable.ml │ ├── identifiable.mli │ ├── int_replace_polymorphic_compare.ml │ ├── int_replace_polymorphic_compare.mli │ ├── lazy_backtrack.ml │ ├── lazy_backtrack.mli │ ├── linkdeps.ml │ ├── linkdeps.mli │ ├── load_path.ml │ ├── load_path.mli │ ├── local_store.ml │ ├── local_store.mli │ ├── misc.ml │ ├── misc.mli │ ├── numbers.ml │ ├── numbers.mli │ ├── profile.ml │ ├── profile.mli │ ├── strongly_connected_components.ml │ ├── strongly_connected_components.mli │ ├── targetint.ml │ ├── targetint.mli │ ├── terminfo.ml │ ├── terminfo.mli │ ├── warnings.ml │ └── warnings.mli └── vim └── merlin ├── autoload ├── ctrlp │ ├── locate.vim │ └── outline.vim ├── merlin.py ├── merlin.vim ├── merlin_find.vim ├── merlin_type.vim ├── merlin_visual.vim └── neomake │ └── makers │ └── ft │ └── ocaml.vim ├── doc └── merlin.txt ├── dune ├── ftdetect └── merlin.vim ├── ftplugin ├── merlin.vim ├── ocaml.vim ├── ocamlinterface.vim ├── ocamllex.vim ├── omlet.vim └── reason.vim ├── plugin └── merlin.vim ├── syntax └── merlin.vim └── syntax_checkers ├── ocaml └── merlin.vim ├── ocamlinterface └── merlin.vim └── omlet └── merlin.vim /.git-blame-ignore-revs: -------------------------------------------------------------------------------- 1 | # git config blame.ignoreRevsFile .git-blame-ignore-revs 2 | 40e0cdb95ff31b81212109fada6e0ff93b6eefee 3 | # Upgrade to OCamlformat 0.27.0 4 | b950681a6853596f072ca9ef7a35cd6a0fe5dc33 5 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | configure eol=lf 2 | *.sh eol=lf 3 | *.patch eol=lf 4 | tests/merlin-wrapper eol=lf 5 | 6 | src/ocaml/preprocess/menhirLib.ml text eol=lf 7 | src/ocaml/preprocess/menhirLib.mli text eol=lf 8 | src/ocaml/preprocess/parser_explain.ml text eol=lf 9 | src/ocaml/preprocess/parser_printer.ml text eol=lf 10 | src/ocaml/preprocess/parser_raw.ml text eol=lf 11 | src/ocaml/preprocess/parser_raw.mli text eol=lf 12 | src/ocaml/preprocess/parser_recover.ml text eol=lf 13 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: github-actions 4 | directory: / 5 | schedule: 6 | interval: weekly 7 | labels: 8 | - no changelog 9 | -------------------------------------------------------------------------------- /.github/fuzzy-ci-helpers/label_name.txt: -------------------------------------------------------------------------------- 1 | fuzzy-diff-looks-good -------------------------------------------------------------------------------- /.github/fuzzy-ci-helpers/msg.txt: -------------------------------------------------------------------------------- 1 | This PR changes the response of some of the `ocamlmerlin` queries, that were 2 | run and analyzed by the 3 | [Merlin Fuzzy CI](https://github.com/ocaml/merlin/wiki/Merlin-Fuzzy-CI). 4 | The change is not considered a regression, the analysis of this PR has been 5 | approved in its following state: | 6 | - URL to download the generated data sets and their diffs between PR base 7 | branch and merge branch (at the moment of approval): $ARTIFACTS_URL | 8 | - 256-sha of full responses diff: $HASH 9 | -------------------------------------------------------------------------------- /.github/workflows/changelog.yml: -------------------------------------------------------------------------------- 1 | name: Changelog check 2 | 3 | on: 4 | pull_request: 5 | branches: [ main ] 6 | types: [ opened, synchronize, reopened, labeled, unlabeled ] 7 | 8 | jobs: 9 | Changelog-Entry-Check: 10 | name: Check Changelog Action 11 | runs-on: ubuntu-20.04 12 | steps: 13 | - uses: tarides/changelog-check-action@v3 14 | -------------------------------------------------------------------------------- /.github/workflows/emacs-lint.yml: -------------------------------------------------------------------------------- 1 | name: Emacs lint 2 | 3 | on: 4 | push: 5 | paths: 6 | - 'emacs/**' 7 | - '**/emacs-lint.yml' 8 | pull_request: 9 | paths: 10 | - 'emacs/**' 11 | - '**/emacs-lint.yml' 12 | 13 | jobs: 14 | build: 15 | runs-on: ubuntu-latest 16 | strategy: 17 | matrix: 18 | emacs_version: 19 | - '27.2' 20 | - '28.2' 21 | - '29.1' 22 | - snapshot 23 | fail-fast: false # don't stop jobs if one fails 24 | env: 25 | EMACS_PACKAGE_LINT_IGNORE: ${{ matrix.package_lint_ignore }} 26 | EMACS_BYTECOMP_WARN_IGNORE: ${{ matrix.bytecomp_warn_ignore }} 27 | steps: 28 | - uses: purcell/setup-emacs@v6.0 29 | with: 30 | version: ${{ matrix.emacs_version }} 31 | 32 | - uses: actions/checkout@v4 33 | - name: Run tests 34 | run: 'cd emacs && ./check.sh' 35 | -------------------------------------------------------------------------------- /.github/workflows/nix.yml: -------------------------------------------------------------------------------- 1 | name: "Nix" 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | paths-ignore: 7 | - '**.md' 8 | - '**.txt' 9 | - '.git*' 10 | - 'doc/**' 11 | - 'emacs/**' 12 | - 'vim/**' 13 | - '**/emacs-lint.yml' 14 | pull_request: 15 | branches: [ master ] 16 | paths-ignore: 17 | - '**.md' 18 | - '**.txt' 19 | - '.git*' 20 | - 'doc/**' 21 | - 'emacs/**' 22 | - 'vim/**' 23 | - '**/emacs-lint.yml' 24 | 25 | jobs: 26 | tests: 27 | runs-on: ubuntu-latest 28 | steps: 29 | - name: Checkout code 30 | uses: actions/checkout@v4 31 | with: 32 | submodules: true 33 | - name: nix 34 | uses: cachix/install-nix-action@31.3.0 35 | with: 36 | nix_path: nixpkgs=channel:nixos-unstable 37 | - run: nix develop -c dune build @check @runtest -p merlin-lib,dot-merlin-reader,ocaml-index,merlin 38 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | _build 2 | _opam 3 | .merlin 4 | jbuild-workspace 5 | dune-workspace 6 | *.install 7 | *.tar.gz 8 | *.pyc 9 | *.cmly 10 | *.elc 11 | 12 | /ocamlmerlin 13 | /ocamlmerlin-server 14 | /ocamlmerlin-lsp 15 | /dot-merlin-reader 16 | 17 | # Ignore garbage files from editors 18 | *.un~ 19 | *.swp 20 | *.swo 21 | .vscode/ -------------------------------------------------------------------------------- /.ocamlformat: -------------------------------------------------------------------------------- 1 | version=0.27.0 2 | disable=false 3 | 4 | break-cases=fit-or-vertical 5 | doc-comments=before 6 | cases-exp-indent=2 7 | dock-collection-brackets=false 8 | # Preserve begin/end 9 | exp-grouping=preserve 10 | module-item-spacing=preserve 11 | parse-docstrings=false 12 | -------------------------------------------------------------------------------- /.ocamlformat-ignore: -------------------------------------------------------------------------------- 1 | upstream/** 2 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | This project has adopted the [OCaml Code of Conduct](https://github.com/ocaml/code-of-conduct/blob/main/CODE_OF_CONDUCT.md). 4 | 5 | # Enforcement 6 | 7 | This project follows the OCaml Code of Conduct 8 | [enforcement policy](https://github.com/ocaml/code-of-conduct/blob/main/CODE_OF_CONDUCT.md#enforcement). 9 | To report any violations, please contact: 10 | 11 | - Sonja Heinze 12 | - Ulysse Gérard 13 | - Pizie Dust 14 | - Xavier Van de Woestyne 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2013 Frédéric Bour, Thomas Refis and Simon Castellan. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: build ocamlmerlin ocamlmerlin-server dot-merlin-reader 2 | 3 | build: 4 | dune build --always-show-command-line 5 | 6 | ocamlmerlin ocamlmerlin-server dot-merlin-reader: 7 | ln -s _build/install/default/bin/$@ ./$@ 8 | 9 | clean: 10 | dune clean 11 | 12 | test: build 13 | dune runtest 14 | 15 | preprocess: 16 | dune build --always-show-command-line @preprocess 17 | 18 | promote: 19 | dune promote 20 | 21 | bench: 22 | merl-an benchmark -p /projects/irmin,/projects/big-bertha -s 1 --data=merl-an_bench 23 | echo "Top 10 slowest queries:" 24 | jq -s "[ (map(.sample_id |= tostring)) + (map(.sample_id |= tostring)) | group_by(.sample_id)[] | select(length > 1) | add ] | sort_by( .responses[0].timing.clock) | reverse | .[:10]" merl-an_bench/query_responses.json merl-an_bench/commands.json 25 | echo "Benchmark result:" 26 | jq . merl-an_bench/bench.json 27 | 28 | .PHONY: all build dev clean test promote bench bench 29 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | platform: 2 | - x64 3 | 4 | clone_depth: 1 5 | 6 | environment: 7 | global: 8 | CYG_ROOT: C:/cygwin 9 | CYG_MIRROR: http://mirrors.kernel.org/sourceware/cygwin/ 10 | CYG_CACHE: C:/cygwin/var/cache/setup 11 | 12 | cache: 13 | # - C:\cygwin\var\cache\setup 14 | - C:\OCaml\4.02 15 | - C:\OCaml\4.03 16 | - C:\OCaml\4.04 17 | - C:\OCaml\4.05 18 | - C:\OCaml\msvs-promote-path 19 | 20 | install: 21 | - '%CYG_ROOT%\bin\bash -lc "date; cygcheck -dc cygwin"' 22 | - '"%CYG_ROOT%\setup-x86.exe" --quiet-mode --no-shortcuts --only-site --root "%CYG_ROOT%" --site "%CYG_MIRROR%" --local-package-dir "%CYG_CACHE%" --packages diffutils,patch,make,mingw64-i686-gcc-core,mingw64-x86_64-gcc-core,unzip > NUL' 23 | - '%CYG_ROOT%\bin\bash -lc "date; cygcheck -dc cygwin"' 24 | 25 | build_script: 26 | - call "%APPVEYOR_BUILD_FOLDER%\appveyor.cmd" 27 | -------------------------------------------------------------------------------- /appveyor/easy-format-1.2.0.patch: -------------------------------------------------------------------------------- 1 | diff -Naur a/Makefile b/Makefile 2 | --- a/Makefile 2015-12-07 21:58:29.000000000 +0000 3 | +++ b/Makefile 2017-07-21 14:19:28.720009800 +0100 4 | @@ -3,6 +3,7 @@ 5 | 6 | NATDYNLINK := $(shell if [ -f `ocamlfind ocamlc -where`/dynlink.cmxa ]; \ 7 | then echo YES; else echo NO; fi) 8 | +EXT_OBJ = $(shell ocamlc -config | sed -ne "s/ext_obj: //p" | tr -d '\r') 9 | 10 | ifeq "${NATDYNLINK}" "YES" 11 | CMXS=easy_format.cmxs 12 | @@ -53,7 +54,7 @@ 13 | caml2html easy_format_example.ml -t -o easy_format_example.html 14 | 15 | soft-clean: 16 | - rm -f *.cm[iox] *.cmxs *.o *.annot \ 17 | + rm -f *.cm[iox] *.cmxs *.o *.obj *.annot \ 18 | test_easy_format lambda_example simple_example \ 19 | bytecode nativecode 20 | 21 | @@ -65,7 +66,7 @@ 22 | 23 | COMMON_INSTALL_FILES = META easy_format.cmi easy_format.mli 24 | BC_INSTALL_FILES = easy_format.cmo 25 | -NC_INSTALL_FILES = easy_format.cmx easy_format.o $(CMXS) 26 | +NC_INSTALL_FILES = easy_format.cmx easy_format$(EXT_OBJ) $(CMXS) 27 | 28 | install: 29 | echo "version = \"$(VERSION)\"" > META; cat META.tpl >> META 30 | -------------------------------------------------------------------------------- /appveyor/findlib-1.7.3.patch: -------------------------------------------------------------------------------- 1 | diff --git a/configure b/configure 2 | index 34c5115..e801760 100755 3 | --- a/configure 4 | +++ b/configure 5 | @@ -191,7 +191,7 @@ for tool in sed awk ocaml ocamlc uname rm make cat m4 dirname basename; do 6 | fi 7 | done 8 | 9 | -lib_suffix=`ocamlc -config 2>/dev/null|grep '^ext_lib'|sed 's/ext_lib: //'` 10 | +lib_suffix=`ocamlc -config 2>/dev/null|tr -d '\015'|sed -n -e 's/^ext_lib: //p'` 11 | 12 | # Check for Cygwin: 13 | 14 | @@ -225,7 +225,7 @@ use_cygpath=0 15 | # Whether we have to translate Unix paths to/from Windows paths. 16 | 17 | if [ -z "$system" ]; then 18 | - system=`ocamlc -config 2>/dev/null|grep '^system'|sed 's/system: //'` 19 | + system=`ocamlc -config 2>/dev/null|tr -d '\015'|sed -n -e 's/^system: //p'` 20 | # This may be 21 | # - mingw or mingw64 22 | # - win32 23 | -------------------------------------------------------------------------------- /doc/next/Protocol.wiki: -------------------------------------------------------------------------------- 1 | Next merlin protocol should be stateless. 2 | Also worth taking a look: [[https://github.com/Microsoft/language-server-protocol|Microsoft/language-server-protocol]]. 3 | 4 | The protocol is still implemented as a series of request/answer. 5 | 6 | {{{ 7 | request-format: 8 | { 9 | uri: "path to current document", 10 | source: "full source text", 11 | setup: merlin-setup, 12 | query: merlin-query, 13 | configuration: { 14 | terminal_width: int, 15 | verbosity: int, 16 | }, 17 | } 18 | 19 | answer-format: 20 | { 21 | class: "return" | "failure" | "error" | "exception", 22 | value: , 23 | notifications: string list 24 | } 25 | 26 | merlin-query: 27 | ... 28 | 29 | merlin-setup: 30 | { 31 | build_path: string list, 32 | source_path: string list, 33 | cmi_path: string list, 34 | cmt_path: string list, 35 | findlib: string, 36 | stdlib: string, 37 | packages: string list, 38 | flags: string list, 39 | reader: string list, 40 | suffixes: (string * string) list 41 | } 42 | }}} 43 | -------------------------------------------------------------------------------- /doc/next/merlin.wiki: -------------------------------------------------------------------------------- 1 | @let-def: this design document gathers requirements and ideas for the next 2 | version of merlin. The purpose is to consolidate features that were added 3 | lately and cleanup legacy cruft. 4 | 5 | == TL;DR == 6 | 7 | * simpler & stateless protocol 8 | * pure implementation for reference 9 | * performance added on top, memoization & asynchronicity 10 | * traceability, log all decisions and print internal structures 11 | * maintenability, minimize change to OCaml codebase 12 | 13 | See [[RATIONALE]]. 14 | 15 | == Implementation == 16 | 17 | Merlin is split in three main components: 18 | 19 | * [[Protocol]], communicates with outside world 20 | * [[Kernel]], wraps the OCaml frontend 21 | * [[Analysis]], answers specific questions on the codebase 22 | -------------------------------------------------------------------------------- /dot-merlin-reader.opam: -------------------------------------------------------------------------------- 1 | opam-version: "2.0" 2 | maintainer: "defree@gmail.com" 3 | authors: "The Merlin team" 4 | synopsis: "Reads config files for merlin" 5 | homepage: "https://github.com/ocaml/merlin" 6 | bug-reports: "https://github.com/ocaml/merlin/issues" 7 | dev-repo: "git+https://github.com/ocaml/merlin.git" 8 | license: "MIT" 9 | x-maintenance-intent: ["(latest)"] 10 | build: [ 11 | ["dune" "subst"] {dev} 12 | ["dune" "build" "-p" name "-j" jobs] 13 | ] 14 | depends: [ 15 | "ocaml" {>= "5.2" } 16 | "dune" {>= "3.0.0"} 17 | "merlin-lib" {= version} 18 | "ocamlfind" {>= "1.6.0"} 19 | ] 20 | description: 21 | "Helper process: reads .merlin files and outputs the normalized content to 22 | stdout." 23 | -------------------------------------------------------------------------------- /dune-project: -------------------------------------------------------------------------------- 1 | (lang dune 3.0) 2 | (name merlin) 3 | (using menhir 2.0) 4 | 5 | (cram enable) 6 | (formatting (enabled_for ocaml)) 7 | (implicit_transitive_deps false) 8 | (use_standard_c_and_cxx_flags true) 9 | -------------------------------------------------------------------------------- /dune-release.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | TAG="$1" 4 | VER="$2" 5 | 6 | if [ -z "$TAG" ]; then 7 | printf "Usage: ./dune-release.sh []\n" 8 | printf "Please make sure that dune-release is available.\n" 9 | exit 1 10 | fi 11 | 12 | FLAGS="-t $TAG" 13 | 14 | if [ -n "$VER" ]; then 15 | FLAGS="$FLAGS --pkg-version=$VER" 16 | fi 17 | 18 | step() 19 | { 20 | printf "Continue? [Yn] " 21 | read action 22 | if [ "x$action" == "xn" ]; then exit 2; fi 23 | if [ "x$action" == "xN" ]; then exit 2; fi 24 | } 25 | 26 | dune-release distrib -p merlin -n merlin $FLAGS --skip-tests #--skip-lint 27 | step 28 | dune-release publish distrib -p merlin -n merlin $FLAGS 29 | step 30 | dune-release opam pkg -p merlin -n merlin $FLAGS 31 | step 32 | dune-release opam submit -p merlin -n merlin $FLAGS 33 | -------------------------------------------------------------------------------- /emacs/dune: -------------------------------------------------------------------------------- 1 | (install 2 | (package merlin) 3 | (section share_root) 4 | (files (merlin-ac.el as emacs/site-lisp/merlin-ac.el) 5 | (merlin-cap.el as emacs/site-lisp/merlin-cap.el) 6 | (merlin-company.el as emacs/site-lisp/merlin-company.el) 7 | (merlin-iedit.el as emacs/site-lisp/merlin-iedit.el) 8 | (merlin-imenu.el as emacs/site-lisp/merlin-imenu.el) 9 | (merlin-xref.el as emacs/site-lisp/merlin-xref.el) 10 | (merlin.el as emacs/site-lisp/merlin.el))) 11 | 12 | -------------------------------------------------------------------------------- /merlin-lib.opam: -------------------------------------------------------------------------------- 1 | opam-version: "2.0" 2 | maintainer: "defree@gmail.com" 3 | authors: "The Merlin team" 4 | homepage: "https://github.com/ocaml/merlin" 5 | bug-reports: "https://github.com/ocaml/merlin/issues" 6 | dev-repo: "git+https://github.com/ocaml/merlin.git" 7 | license: "MIT" 8 | x-maintenance-intent: ["(latest)"] 9 | build: [ 10 | ["dune" "subst"] {dev} 11 | ["dune" "build" "-p" name "-j" jobs] 12 | ] 13 | depends: [ 14 | "ocaml" {>="5.3" & <"5.4"} 15 | "dune" {>= "3.0.0"} 16 | "csexp" {>= "1.5.1"} 17 | "alcotest" {with-test & >= "1.3.0" } 18 | "menhir" {dev & >= "20201216"} 19 | "menhirLib" {dev & >= "20201216"} 20 | "menhirSdk" {dev & >= "20201216"} 21 | ] 22 | synopsis: 23 | "Merlin's libraries" 24 | description: 25 | "These libraries provides access to low-level compiler interfaces and the 26 | standard higher-level merlin protocol. The library is provided as-is, is not 27 | thoroughly documented, and its public API might break with any new release." 28 | -------------------------------------------------------------------------------- /ocaml-index.opam: -------------------------------------------------------------------------------- 1 | opam-version: "2.0" 2 | synopsis: "A tool that indexes value usages from cmt files" 3 | description: 4 | "ocaml-index should integrate with the build system to index codebase and allow tools such as Merlin to perform project-wide occurrences queries." 5 | maintainer: ["ulysse@tarides.com"] 6 | authors: ["ulysse@tarides.com"] 7 | license: "MIT" 8 | homepage: "https://github.com/ocaml/merlin/ocaml-index" 9 | bug-reports: "https://github.com/ocaml/merlin/issues" 10 | x-maintenance-intent: ["(latest)"] 11 | depends: [ 12 | "dune" {>= "3.0.0"} 13 | "ocaml" {>= "5.3"} 14 | "merlin-lib" {= version} 15 | "odoc" {with-doc} 16 | ] 17 | build: [ 18 | ["dune" "subst"] {dev} 19 | [ 20 | "dune" 21 | "build" 22 | "-p" 23 | name 24 | "-j" 25 | jobs 26 | "--promote-install-files=false" 27 | "@install" 28 | "@runtest" {with-test} 29 | "@doc" {with-doc} 30 | ] 31 | ["dune" "install" "-p" name "--create-install-files" name] 32 | ] 33 | dev-repo: "git+https://github.com/ocaml/merlin.git" 34 | -------------------------------------------------------------------------------- /src/analysis/construct.mli: -------------------------------------------------------------------------------- 1 | exception Not_allowed of string 2 | exception Not_a_hole 3 | 4 | type values_scope = Null | Local 5 | 6 | val node : 7 | ?depth:int -> 8 | config:Mconfig.t -> 9 | keywords:string list -> 10 | values_scope:values_scope -> 11 | Browse_raw.node -> 12 | string list 13 | -------------------------------------------------------------------------------- /src/analysis/dune: -------------------------------------------------------------------------------- 1 | (library 2 | (name merlin_analysis) 3 | (public_name merlin-lib.analysis) 4 | (flags 5 | :standard 6 | -open Ocaml_utils 7 | -open Ocaml_parsing 8 | -open Ocaml_preprocess 9 | -open Ocaml_typing 10 | -open Merlin_utils 11 | -open Merlin_specific 12 | -open Merlin_extend 13 | -open Merlin_kernel 14 | -open Merlin_index_format) 15 | (libraries 16 | merlin_config 17 | merlin_specific 18 | merlin_extend 19 | merlin_kernel 20 | merlin_utils 21 | merlin_index_format 22 | merlin_sherlodoc 23 | ocaml_parsing 24 | ocaml_preprocess 25 | query_protocol 26 | ocaml_typing 27 | ocaml_utils 28 | str 29 | unix)) 30 | -------------------------------------------------------------------------------- /src/analysis/expansion.mli: -------------------------------------------------------------------------------- 1 | type t 2 | 3 | val explore : ?global_modules:string list -> Env.t -> t list 4 | 5 | val get_lidents : t list -> string -> Longident.t option list * string 6 | 7 | val spell_index : string -> string -> bool 8 | 9 | val spell_match : (string -> bool) -> string -> bool 10 | -------------------------------------------------------------------------------- /src/analysis/inlay_hints.mli: -------------------------------------------------------------------------------- 1 | (** Builds the list of inlay hints to be displayed on a document. *) 2 | 3 | type hint = Lexing.position * string 4 | 5 | val of_structure : 6 | hint_let_binding:bool -> 7 | hint_pattern_binding:bool -> 8 | hint_function_params:bool -> 9 | avoid_ghost_location:bool -> 10 | start:Lexing.position -> 11 | stop:Lexing.position -> 12 | Typedtree.structure -> 13 | hint list 14 | -------------------------------------------------------------------------------- /src/analysis/occurrences.mli: -------------------------------------------------------------------------------- 1 | type t = 2 | { occurrences : Query_protocol.occurrence list; 3 | status : Query_protocol.occurrences_status 4 | } 5 | 6 | val locs_of : 7 | config:Mconfig.t -> 8 | env:Env.t -> 9 | typer_result:Mtyper.result -> 10 | pos:Lexing.position -> 11 | scope:[ `Project | `Buffer | `Renaming ] -> 12 | string -> 13 | t 14 | -------------------------------------------------------------------------------- /src/analysis/parsetree_utils.ml: -------------------------------------------------------------------------------- 1 | open Parsetree 2 | 3 | type nonrec constant_desc = constant_desc 4 | 5 | let constant_desc c = c.pconst_desc 6 | -------------------------------------------------------------------------------- /src/analysis/parsetree_utils.mli: -------------------------------------------------------------------------------- 1 | (** Utilities to provide a slightly more stable Parsetree API for alternative 2 | clients like [ocaml-lsp]. *) 3 | 4 | open Parsetree 5 | 6 | type nonrec constant_desc = constant_desc 7 | 8 | val constant_desc : constant -> constant_desc 9 | -------------------------------------------------------------------------------- /src/analysis/ppx_expand.mli: -------------------------------------------------------------------------------- 1 | type ppx_kind = 2 | | Expr of Parsetree.expression 3 | | Sig_item of Parsetree.signature_item 4 | | Str_item of Parsetree.structure_item 5 | 6 | val check_extension : 7 | parsetree: 8 | [ `Implementation of Parsetree.structure 9 | | `Interface of Parsetree.signature ] -> 10 | pos:Lexing.position -> 11 | (ppx_kind * Warnings.loc) option 12 | 13 | val get_ppxed_source : 14 | ppxed_parsetree: 15 | [ `Implementation of Parsetree.structure 16 | | `Interface of Parsetree.signature ] -> 17 | pos:Lexing.position -> 18 | ppx_kind * Warnings.loc -> 19 | Query_protocol.ppxed_source 20 | -------------------------------------------------------------------------------- /src/analysis/refactor_open.mli: -------------------------------------------------------------------------------- 1 | val get_rewrites : 2 | mode:[> `Qualify | `Unqualify ] -> 3 | Mtyper.result -> 4 | Lexing.position -> 5 | (string * Location.t) list 6 | -------------------------------------------------------------------------------- /src/analysis/signature_help.mli: -------------------------------------------------------------------------------- 1 | type parameter_info = 2 | { label : Asttypes.arg_label; 3 | param_start : int; 4 | param_end : int; 5 | argument : Typedtree.expression option 6 | } 7 | 8 | type application_signature = 9 | { function_name : string option; 10 | function_position : Msource.position; 11 | signature : string; 12 | parameters : parameter_info list; 13 | active_param : int option 14 | } 15 | 16 | (** provide signature information for applied functions *) 17 | val application_signature : 18 | prefix:string -> 19 | cursor:Lexing.position -> 20 | Mbrowse.t -> 21 | application_signature option 22 | 23 | (** @see reference *) 24 | val prefix_of_position : 25 | short_path:bool -> Msource.t -> Msource.position -> string 26 | -------------------------------------------------------------------------------- /src/analysis/syntax_doc.mli: -------------------------------------------------------------------------------- 1 | val get_syntax_doc : 2 | Lexing.position -> 3 | (Env.t * Browse_raw.node) list -> 4 | Query_protocol.syntax_doc_result option 5 | -------------------------------------------------------------------------------- /src/analysis/typed_hole.ml: -------------------------------------------------------------------------------- 1 | let syntax_repr = "_" 2 | let can_be_hole s = String.equal syntax_repr s 3 | 4 | (* the pattern matching below is taken and modified (minimally, to adapt the 5 | return type) from [Query_commands.dispatch]'s [Construct] branch; 6 | 7 | If we directly dispatched [Construct] command to merlin, we'd be doing 8 | useless computations: we need info whether the expression at the cursor is a 9 | hole, we don't need constructed expressions yet. 10 | 11 | Ideally, merlin should return a callback [option], which is [Some] when the 12 | context is applicable. *) 13 | let is_a_hole = function 14 | | (_, Browse_raw.Module_expr { mod_desc = Tmod_typed_hole; _ }) :: (_, _) :: _ 15 | | (_, Browse_raw.Expression { exp_desc = Texp_typed_hole; _ }) :: _ -> true 16 | | [] | (_, _) :: _ -> false 17 | ;; 18 | -------------------------------------------------------------------------------- /src/analysis/typed_hole.mli: -------------------------------------------------------------------------------- 1 | (** This module should be used to work with typed holes. The main goal is to 2 | hide syntactic representation of a typed hole, which may change in future *) 3 | 4 | (** checks whether the current string matches the syntax representation of a 5 | typed hole *) 6 | val can_be_hole : string -> bool 7 | 8 | (** [is_a_hole nodes] checks whether the leaf node [1] is a typed hole 9 | 10 | Note: this function is extracted from merlin sources handling [Construct] 11 | command in [merlin/src/frontend/query_commands.ml] 12 | 13 | [1] leaf node is the head of the list, as 14 | [Mbrowse.t = (Env.t * Browse_raw.node) list]*) 15 | val is_a_hole : Mbrowse.t -> bool 16 | -------------------------------------------------------------------------------- /src/commands/dune: -------------------------------------------------------------------------------- 1 | (library 2 | (name merlin_commands) 3 | (public_name merlin-lib.commands) 4 | (flags 5 | :standard 6 | -open Ocaml_parsing 7 | -open Merlin_utils 8 | -open Merlin_kernel) 9 | (libraries 10 | merlin-lib.ocaml_parsing 11 | merlin-lib.utils 12 | merlin-lib.kernel 13 | merlin-lib.query_protocol 14 | merlin-lib.query_commands)) 15 | -------------------------------------------------------------------------------- /src/config/dune: -------------------------------------------------------------------------------- 1 | (rule 2 | (targets merlin_config.ml) 3 | (deps gen_config.ml) 4 | (action (with-stdout-to %{targets} 5 | (run %{ocaml} gen_config.ml %{ocaml_version})))) 6 | 7 | (library 8 | (name merlin_config) 9 | (public_name merlin-lib.config) 10 | (modules merlin_config)) 11 | -------------------------------------------------------------------------------- /src/config/gen_config.ml: -------------------------------------------------------------------------------- 1 | let ocaml_version_val = 2 | match 3 | Scanf.sscanf Sys.argv.(1) "%s@.%s@.%d" (fun maj min p -> (maj, min, p)) 4 | with 5 | | "4", "02", _ -> "`OCaml_4_02_3" 6 | | "4", "07", p -> Printf.sprintf "`OCaml_4_07_%d" p 7 | | maj, min, _ -> Printf.sprintf "`OCaml_%s_%s_0" maj min 8 | 9 | let () = 10 | Printf.printf 11 | {| 12 | let version = "%%VERSION%%" 13 | let ocamlversion : 14 | [ `OCaml_4_02_0 | `OCaml_4_02_1 | `OCaml_4_02_2 | `OCaml_4_02_3 15 | | `OCaml_4_03_0 | `OCaml_4_04_0 | `OCaml_4_05_0 | `OCaml_4_06_0 16 | | `OCaml_4_07_0 | `OCaml_4_07_1 | `OCaml_4_08_0 | `OCaml_4_09_0 17 | | `OCaml_4_10_0 | `OCaml_4_11_0 | `OCaml_4_12_0 | `OCaml_4_13_0 18 | | `OCaml_4_14_0 | `OCaml_5_0_0 | `OCaml_5_1_0 | `OCaml_5_2_0 19 | | `OCaml_5_3_0 ] = %s 20 | |} 21 | ocaml_version_val 22 | -------------------------------------------------------------------------------- /src/dot-merlin/dune: -------------------------------------------------------------------------------- 1 | (executable 2 | (package dot-merlin-reader) 3 | (name dot_merlin_reader) 4 | (public_name dot-merlin-reader) 5 | (libraries findlib merlin-lib.utils merlin-lib.dot_protocol str unix)) 6 | -------------------------------------------------------------------------------- /src/dot-protocol/dune: -------------------------------------------------------------------------------- 1 | (library 2 | (name merlin_dot_protocol) 3 | (public_name merlin-lib.dot_protocol) 4 | (libraries merlin_utils csexp)) 5 | -------------------------------------------------------------------------------- /src/extend/.gitignore: -------------------------------------------------------------------------------- 1 | *.annot 2 | *.cmo 3 | *.cma 4 | *.cmi 5 | *.a 6 | *.o 7 | *.cmx 8 | *.cmxs 9 | *.cmxa 10 | 11 | # ocamlbuild working directory 12 | _build/ 13 | 14 | # ocamlbuild targets 15 | *.byte 16 | *.native 17 | 18 | # oasis generated files 19 | setup.data 20 | setup.log 21 | -------------------------------------------------------------------------------- /src/extend/dune: -------------------------------------------------------------------------------- 1 | (library 2 | (name merlin_extend) 3 | (public_name merlin-lib.extend) 4 | (modules (:standard \ extend_helper)) 5 | (flags :standard -open Ocaml_utils -open Ocaml_parsing -open Ocaml_typing) 6 | (libraries ocaml_parsing ocaml_typing unix ocaml_utils)) 7 | -------------------------------------------------------------------------------- /src/extend/extend_driver.mli: -------------------------------------------------------------------------------- 1 | (** Helper for the driver (Merlin) *) 2 | open Extend_protocol 3 | 4 | type t 5 | 6 | exception Extension of string * string * string 7 | 8 | val run : ?notify:(string -> unit) -> ?debug:(string -> unit) -> string -> t 9 | 10 | val stop : t -> unit 11 | 12 | val capabilities : t -> capabilities 13 | 14 | val reader : t -> Reader.request -> Reader.response 15 | -------------------------------------------------------------------------------- /src/extend/extend_main.mli: -------------------------------------------------------------------------------- 1 | open Extend_protocol 2 | 3 | module Description : sig 4 | type t 5 | val make_v0 : name:string -> version:string -> t 6 | end 7 | 8 | module Utils : sig 9 | val notify : string -> unit 10 | val debug : string -> unit 11 | end 12 | 13 | module Reader : sig 14 | type t 15 | val make_v0 : (module Reader.V0) -> t 16 | end 17 | 18 | module Handshake : sig 19 | val magic_number : string 20 | 21 | type versions = 22 | { ast_impl_magic_number : string; 23 | ast_intf_magic_number : string; 24 | cmi_magic_number : string; 25 | cmt_magic_number : string 26 | } 27 | 28 | exception Error of string 29 | 30 | val versions : versions 31 | 32 | val negotiate_driver : string -> in_channel -> out_channel -> capabilities 33 | end 34 | 35 | (** The main entry point of an extension. *) 36 | val extension_main : ?reader:Reader.t -> Description.t -> 'a 37 | -------------------------------------------------------------------------------- /src/frontend/dune: -------------------------------------------------------------------------------- 1 | (library 2 | (name query_protocol) 3 | (public_name merlin-lib.query_protocol) 4 | (modules query_protocol) 5 | (flags :standard -open Merlin_utils -open Merlin_kernel -open Ocaml_parsing -open Merlin_kernel) 6 | (libraries merlin_kernel merlin_utils ocaml_parsing)) 7 | 8 | (library 9 | (name query_commands) 10 | (public_name merlin-lib.query_commands) 11 | (modules query_commands) 12 | (flags 13 | :standard 14 | -open Ocaml_utils 15 | -open Ocaml_parsing 16 | -open Ocaml_typing 17 | -open Merlin_kernel 18 | -open Merlin_specific 19 | -open Merlin_utils 20 | -open Merlin_specific 21 | -open Merlin_analysis 22 | -open Merlin_kernel) 23 | (libraries 24 | merlin_utils 25 | merlin_kernel 26 | ocaml_utils 27 | ocaml_parsing 28 | ocaml_typing 29 | merlin_specific 30 | merlin_config 31 | merlin_analysis 32 | merlin_sherlodoc 33 | query_protocol 34 | str)) 35 | -------------------------------------------------------------------------------- /src/frontend/ocamlmerlin/gen_ccflags.ml: -------------------------------------------------------------------------------- 1 | let ccomp_type = Sys.argv.(1) 2 | let pre_flags_f = Sys.argv.(2) 3 | let post_flags_f = Sys.argv.(3) 4 | 5 | let pre_flags, post_flags = 6 | if Str.string_match (Str.regexp "msvc") ccomp_type 0 then 7 | ("/Fe", "advapi32.lib") 8 | else ("-o", "") 9 | 10 | let write_lines f s = 11 | let oc = open_out f in 12 | output_string oc s; 13 | close_out oc 14 | 15 | let () = 16 | write_lines pre_flags_f pre_flags; 17 | write_lines post_flags_f post_flags 18 | -------------------------------------------------------------------------------- /src/frontend/ocamlmerlin/log_info.ml: -------------------------------------------------------------------------------- 1 | let get () = 2 | let log_file, sections = 3 | match String.split_on_char ',' (Sys.getenv "MERLIN_LOG") with 4 | | value :: sections -> (Some value, sections) 5 | | [] -> (None, []) 6 | | exception Not_found -> (None, []) 7 | in 8 | (`Log_file_path log_file, `Log_sections sections) 9 | -------------------------------------------------------------------------------- /src/frontend/ocamlmerlin/log_info.mli: -------------------------------------------------------------------------------- 1 | val get : 2 | unit -> [ `Log_file_path of string option ] * [ `Log_sections of string list ] 3 | -------------------------------------------------------------------------------- /src/frontend/ocamlmerlin/old/old_merlin.mli: -------------------------------------------------------------------------------- 1 | val run : string list -> 'a 2 | -------------------------------------------------------------------------------- /src/index-format/dune: -------------------------------------------------------------------------------- 1 | (library 2 | (name merlin_index_format) 3 | (public_name merlin-lib.index_format) 4 | (flags 5 | :standard 6 | -open Ocaml_parsing 7 | -open Ocaml_typing 8 | -open Ocaml_utils 9 | -open Merlin_utils) 10 | (libraries ocaml_parsing ocaml_typing ocaml_utils merlin_utils)) 11 | -------------------------------------------------------------------------------- /src/index-format/index_cache.ml: -------------------------------------------------------------------------------- 1 | include File_cache.Make (struct 2 | type t = Index_format.index 3 | let read file = Index_format.read_exn ~file 4 | let cache_name = "Index_cache" 5 | end) 6 | -------------------------------------------------------------------------------- /src/kernel/dune: -------------------------------------------------------------------------------- 1 | (rule (copy# ../ocaml/driver/pparse.ml pparse.ml )) 2 | (rule (copy# ../ocaml/driver/pparse.mli pparse.mli)) 3 | 4 | (library 5 | (name merlin_kernel) 6 | (public_name merlin-lib.kernel) 7 | (flags 8 | :standard 9 | -open Ocaml_utils 10 | -open Merlin_utils 11 | -open Ocaml_parsing 12 | -open Ocaml_preprocess 13 | -open Ocaml_typing 14 | -open Merlin_specific 15 | -open Merlin_extend) 16 | (libraries merlin_config os_ipc ocaml_parsing ocaml_preprocess ocaml_typing 17 | ocaml_utils merlin_extend merlin_specific merlin_utils 18 | merlin_dot_protocol merlin_index_format unix str)) 19 | 20 | (rule 21 | (targets standard_library.ml) 22 | (action 23 | (write-file %{targets} "let path = {|%{ocaml-config:standard_library}|}"))) 24 | -------------------------------------------------------------------------------- /src/kernel/mocaml.mli: -------------------------------------------------------------------------------- 1 | (* An instance of load path, environment cache & btype unification log *) 2 | type typer_state 3 | 4 | val new_state : unit -> typer_state 5 | val with_state : typer_state -> (unit -> 'a) -> 'a 6 | val is_current_state : typer_state -> bool 7 | 8 | (* Build settings *) 9 | val setup_reader_config : Mconfig.t -> unit 10 | val setup_typer_config : Mconfig.t -> unit 11 | 12 | (* Replace Outcome printer *) 13 | val default_printer : 14 | Format.formatter -> Extend_protocol.Reader.outcometree -> unit 15 | 16 | val with_printer : 17 | (Format.formatter -> Extend_protocol.Reader.outcometree -> unit) -> 18 | (unit -> 'a) -> 19 | 'a 20 | 21 | (* Clear caches, remove all items *) 22 | val clear_caches : unit -> unit 23 | 24 | (* Flush caches, remove outdated items *) 25 | val flush_caches : ?older_than:float -> unit -> unit 26 | -------------------------------------------------------------------------------- /src/kernel/mpipeline.mli: -------------------------------------------------------------------------------- 1 | type t 2 | val make : Mconfig.t -> Msource.t -> t 3 | val with_pipeline : t -> (unit -> 'a) -> 'a 4 | val for_completion : Msource.position -> t -> t 5 | 6 | val raw_source : t -> Msource.t 7 | 8 | val input_config : t -> Mconfig.t 9 | val input_source : t -> Msource.t 10 | val get_lexing_pos : t -> [< Msource.position ] -> Lexing.position 11 | 12 | val reader_config : t -> Mconfig.t 13 | val reader_comments : t -> (string * Location.t) list 14 | val reader_parsetree : t -> Mreader.parsetree 15 | val reader_lexer_keywords : t -> string list 16 | val reader_lexer_errors : t -> exn list 17 | val reader_parser_errors : t -> exn list 18 | val reader_no_labels_for_completion : t -> bool 19 | 20 | val ppx_parsetree : t -> Mreader.parsetree 21 | val ppx_errors : t -> exn list 22 | 23 | val final_config : t -> Mconfig.t 24 | 25 | val typer_result : t -> Mtyper.result 26 | val typer_errors : t -> exn list 27 | 28 | val timing_information : t -> (string * float) list 29 | val cache_information : t -> Std.json 30 | -------------------------------------------------------------------------------- /src/kernel/mppx.mli: -------------------------------------------------------------------------------- 1 | val rewrite : Mreader.parsetree -> Mconfig.t -> Mreader.parsetree 2 | -------------------------------------------------------------------------------- /src/kernel/mreader_extend.mli: -------------------------------------------------------------------------------- 1 | type t 2 | 3 | val stop : t -> unit 4 | 5 | val start : string -> string list -> Mconfig.t -> Msource.t -> t option 6 | 7 | val parse : 8 | ?for_completion:Msource.position -> 9 | t -> 10 | ([ `No_labels of bool ] 11 | * [ `Implementation of Parsetree.structure 12 | | `Interface of Parsetree.signature ]) 13 | option 14 | 15 | val reconstruct_identifier : 16 | Lexing.position -> t -> string Location.loc list option 17 | 18 | val print_pretty : Extend_protocol.Reader.pretty_parsetree -> t -> string option 19 | 20 | val print_outcomes : 21 | Extend_protocol.Reader.outcometree list -> t -> string list option 22 | 23 | val print_outcome : Extend_protocol.Reader.outcometree -> t -> string option 24 | -------------------------------------------------------------------------------- /src/kernel/msource.mli: -------------------------------------------------------------------------------- 1 | (** {0 Merlin representation of a textual source code} 2 | 3 | It bundles filename and a content, and offers functions for computing 4 | positions in the source. 5 | *) 6 | type t 7 | 8 | module Digest : sig 9 | (** Minimal [Digest] utilities around [t]*) 10 | 11 | type source 12 | type t 13 | 14 | val make : source -> t 15 | val equal : t -> t -> bool 16 | end 17 | with type source := t 18 | 19 | (** Making a content from name and contents. *) 20 | val make : string -> t 21 | 22 | (** {1 Position management} *) 23 | 24 | type position = [ `Start | `Offset of int | `Logical of int * int | `End ] 25 | 26 | val get_offset : t -> [< position ] -> [> `Offset of int ] 27 | 28 | val get_logical : t -> [< position ] -> [> `Logical of int * int ] 29 | 30 | val get_lexing_pos : t -> filename:string -> [< position ] -> Lexing.position 31 | 32 | (** {1 Managing content} *) 33 | 34 | (** Updating content *) 35 | val substitute : 36 | t -> [< position ] -> [< position | `Length of int ] -> string -> t 37 | 38 | (** Source code of the file *) 39 | val text : t -> string 40 | 41 | val dump : t -> Std.json 42 | 43 | val print_position : unit -> [< position ] -> string 44 | -------------------------------------------------------------------------------- /src/ocaml-index/CHANGES.md: -------------------------------------------------------------------------------- 1 | 1.0 (2024-06-18) 2 | ---------------- 3 | 4 | ### Added 5 | 6 | - Initial release. 7 | - The `aggregate`` command that finishes reduction of shapes in cmt files and 8 | store the output in a single index file. 9 | - The `stats` command that prints information about an index file. 10 | - The `dump` command that prints all locs of an index. 11 | -------------------------------------------------------------------------------- /src/ocaml-index/bin/dune: -------------------------------------------------------------------------------- 1 | (executable 2 | (name ocaml_index) 3 | (public_name ocaml-index) 4 | (package ocaml-index) 5 | (libraries lib ocaml_typing ocaml_utils merlin_index_format) 6 | (flags 7 | :standard 8 | -open Ocaml_typing 9 | -open Ocaml_utils 10 | -open Merlin_index_format)) 11 | -------------------------------------------------------------------------------- /src/ocaml-index/lib/dune: -------------------------------------------------------------------------------- 1 | (library 2 | (name lib) 3 | (libraries ocaml_typing ocaml_parsing ocaml_utils merlin_utils 4 | merlin_analysis merlin_index_format unix) 5 | (flags :standard -open Ocaml_typing -open Ocaml_parsing -open Ocaml_utils 6 | -open Merlin_utils -open Merlin_analysis -open Merlin_index_format)) 7 | -------------------------------------------------------------------------------- /src/ocaml-index/lib/log.ml: -------------------------------------------------------------------------------- 1 | module Level = struct 2 | type t = Debug | Warning | Error 3 | 4 | let int_of_t = function 5 | | Debug -> 0 6 | | Warning -> 1 7 | | Error -> 2 8 | 9 | let string_of_t = function 10 | | Debug -> "debug" 11 | | Warning -> "warning" 12 | | Error -> "error" 13 | 14 | let ( >= ) a b = int_of_t a >= int_of_t b 15 | end 16 | 17 | let log_level = ref Level.Error 18 | let set_log_level level = log_level := level 19 | 20 | let log ~level = 21 | let print = 22 | let formatter = 23 | if level = Level.Error then Format.err_formatter else Format.std_formatter 24 | in 25 | Format.fprintf formatter "[%s] %s\n%!" (Level.string_of_t level) 26 | in 27 | if Level.(level >= !log_level) then Format.kasprintf print 28 | else Format.ikfprintf ignore Format.std_formatter 29 | 30 | let debug fmt = log ~level:Level.Debug fmt 31 | let warn fmt = log ~level:Level.Warning fmt 32 | let error fmt = log ~level:Level.Error fmt 33 | -------------------------------------------------------------------------------- /src/ocaml-index/lib/log.mli: -------------------------------------------------------------------------------- 1 | module Level : sig 2 | type t = Debug | Warning | Error 3 | end 4 | 5 | val set_log_level : Level.t -> unit 6 | val log : level:Level.t -> ('a, Format.formatter, unit, unit) format4 -> 'a 7 | val debug : ('a, Format.formatter, unit, unit) format4 -> 'a 8 | val warn : ('a, Format.formatter, unit, unit) format4 -> 'a 9 | val error : ('a, Format.formatter, unit, unit) format4 -> 'a 10 | -------------------------------------------------------------------------------- /src/ocaml-index/tests/dune: -------------------------------------------------------------------------------- 1 | (alias 2 | (name ocaml-index-test-deps) 3 | (deps 4 | (package ocaml-index))) 5 | 6 | (cram 7 | (package ocaml-index) 8 | (applies_to :whole_subtree) 9 | (deps 10 | (alias ocaml-index-test-deps))) 11 | -------------------------------------------------------------------------------- /src/ocaml-index/tests/tests-dirs/cmd.t: -------------------------------------------------------------------------------- 1 | $ ocaml-index aggregate 2 | $ ocaml-index aggregate --debug 3 | [debug] Debug log is enabled 4 | 5 | $ ocaml-index --help 6 | ocaml-index [COMMAND] [-verbose] [] ... -o 7 | --verbose Output more information 8 | --debug Output debugging information 9 | -o Set output file name 10 | --root Set the root path for all relative locations 11 | --rewrite-root Rewrite locations paths using the provided root 12 | --store-shapes Aggregate input-indexes shapes and store them in the new index 13 | -I An extra directory to add to the load path 14 | -H An extra hidden directory to add to the load path 15 | --no-cmt-load-path Do not initialize the load path with the paths found in the first input cmt file 16 | -help Display this list of options 17 | --help Display this list of options 18 | -------------------------------------------------------------------------------- /src/ocaml-index/tests/tests-dirs/flags.t: -------------------------------------------------------------------------------- 1 | $ cat >main.ml < let x = 42 3 | > let () = print_int x 4 | > EOF 5 | 6 | $ ocamlc -bin-annot -bin-annot-occurrences -c main.ml 7 | 8 | $ ocaml-index aggregate main.cmt 9 | 10 | Default output file: 11 | $ ls project.ocaml-index 12 | project.ocaml-index 13 | 14 | Set output file: 15 | $ ocaml-index aggregate main.cmt -o out 16 | $ ls out 17 | out 18 | 19 | No root dir was given: 20 | $ ocaml-index stats project.ocaml-index | grep root 21 | - root dir: none 22 | 23 | We provide one: 24 | $ ocaml-index aggregate main.cmt --root /tmp/ 25 | $ ocaml-index stats project.ocaml-index | grep root 26 | - root dir: /tmp/ 27 | 28 | Rewrite locations: 29 | $ ocaml-index aggregate main.cmt --root /tmp/ --rewrite-root 30 | $ ocaml-index dump project.ocaml-index | grep File 31 | "x": File "/tmp/main.ml", line 1, characters 4-5; 32 | "x": File "/tmp/main.ml", line 2, characters 19-20 33 | "print_int": File "/tmp/main.ml", line 2, characters 9-18 34 | -------------------------------------------------------------------------------- /src/ocaml-index/tests/tests-dirs/interfaces.t: -------------------------------------------------------------------------------- 1 | $ cat >main.mli <<'EOF' 2 | > type t = Float.t 3 | > EOF 4 | 5 | $ ocamlc -bin-annot -bin-annot-occurrences -c main.mli 6 | 7 | $ ls 8 | main.cmi 9 | main.cmti 10 | main.mli 11 | 12 | $ ocamlobjinfo -quiet -index main.cmti 13 | Indexed shapes: 14 | Unresolved: CU Stdlib . "Float"[module] . "t"[type] : 15 | Float.t (File "main.mli", line 1, characters 9-16) 16 | 17 | $ ocaml-index aggregate main.cmti -o main.index 18 | 19 | $ ocaml-index dump main.index 20 | 2 uids: 21 | {uid: [intf]Main.0; locs: "t": File "main.mli", line 1, characters 5-6 22 | uid: Stdlib__Float.81; locs: 23 | "Float.t": File "main.mli", line 1, characters 9-16 24 | }, 0 approx shapes: {}, and shapes for CUS . 25 | and related uids:{} 26 | -------------------------------------------------------------------------------- /src/ocaml/.ocamlformat: -------------------------------------------------------------------------------- 1 | disable=true 2 | -------------------------------------------------------------------------------- /src/ocaml/.ocamlformat-enable: -------------------------------------------------------------------------------- 1 | merlin_specific/** 2 | -------------------------------------------------------------------------------- /src/ocaml/compression/dune: -------------------------------------------------------------------------------- 1 | (library 2 | (name ocaml_compression) 3 | (public_name merlin-lib.ocaml_compression) 4 | (libraries compiler-libs.common)) 5 | -------------------------------------------------------------------------------- /src/ocaml/compression/ocaml_compression.ml: -------------------------------------------------------------------------------- 1 | 2 | (** We rely on [compiler-libs] for compression *) 3 | include Compression 4 | -------------------------------------------------------------------------------- /src/ocaml/merlin_specific/dune: -------------------------------------------------------------------------------- 1 | (library 2 | (name merlin_specific) 3 | (public_name merlin-lib.ocaml_merlin_specific) 4 | (flags 5 | :standard 6 | -open Ocaml_utils 7 | -open Ocaml_parsing 8 | -open Ocaml_preprocess 9 | -open Ocaml_typing 10 | -open Ocaml_preprocess 11 | -open Merlin_utils) 12 | (libraries merlin_utils ocaml_parsing ocaml_preprocess ocaml_typing ocaml_utils)) 13 | -------------------------------------------------------------------------------- /src/ocaml/parsing/.ocamlformat-enable: -------------------------------------------------------------------------------- 1 | msupport_parsing.ml 2 | -------------------------------------------------------------------------------- /src/ocaml/parsing/dune: -------------------------------------------------------------------------------- 1 | (rule (copy# ../../extend/extend_helper.ml extend_helper.ml )) 2 | (rule (copy# ../../extend/extend_helper.mli extend_helper.mli)) 3 | 4 | (library 5 | (name ocaml_parsing) 6 | (public_name merlin-lib.ocaml_parsing) 7 | (flags -open Ocaml_utils -open Merlin_utils (:standard -w -9)) 8 | (modules_without_implementation parsetree) 9 | (libraries merlin_utils ocaml_utils)) 10 | -------------------------------------------------------------------------------- /src/ocaml/parsing/lexer.ml: -------------------------------------------------------------------------------- 1 | (* This forward reference is filled in Lexer_raw.mll *) 2 | let is_keyword_ref : (string -> bool) ref = ref (fun _ -> false) 3 | let is_keyword txt = !is_keyword_ref txt 4 | -------------------------------------------------------------------------------- /src/ocaml/parsing/msupport_parsing.ml: -------------------------------------------------------------------------------- 1 | (* Filled in from Msupport. *) 2 | let msupport_raise_error : (exn -> unit) ref = ref raise 3 | 4 | let raise_error exn = !msupport_raise_error exn 5 | -------------------------------------------------------------------------------- /src/ocaml/preprocess/explain/dune: -------------------------------------------------------------------------------- 1 | (executable 2 | (name gen_explain) 3 | (libraries unix menhirSdk)) 4 | -------------------------------------------------------------------------------- /src/ocaml/preprocess/parser_printer.mli: -------------------------------------------------------------------------------- 1 | open Parser_raw 2 | 3 | val print_symbol : MenhirInterpreter.xsymbol -> string 4 | val print_value : 'a MenhirInterpreter.symbol -> 'a -> string 5 | val print_token : token -> string 6 | val token_of_terminal : 'a MenhirInterpreter.terminal -> 'a -> token 7 | -------------------------------------------------------------------------------- /src/ocaml/preprocess/parser_recover.mli: -------------------------------------------------------------------------------- 1 | open Parser_raw 2 | 3 | module Default : sig 4 | val default_loc : Location.t ref 5 | end 6 | 7 | val default_value : 'a MenhirInterpreter.symbol -> 'a 8 | 9 | type action = 10 | | Abort 11 | | R of int 12 | | S : 'a MenhirInterpreter.symbol -> action 13 | | Sub of action list 14 | 15 | type decision = 16 | | Nothing 17 | | One of action list 18 | | Select of (int -> action list) 19 | 20 | val depth : int array 21 | 22 | val can_pop : 'a MenhirInterpreter.terminal -> bool 23 | 24 | val recover : int -> decision 25 | -------------------------------------------------------------------------------- /src/ocaml/preprocess/printer/dune: -------------------------------------------------------------------------------- 1 | (executable 2 | (name gen_printer) 3 | (libraries unix menhirSdk)) 4 | -------------------------------------------------------------------------------- /src/ocaml/preprocess/recover/compressedBitSet.mli: -------------------------------------------------------------------------------- 1 | (******************************************************************************) 2 | (* *) 3 | (* Menhir *) 4 | (* *) 5 | (* François Pottier, Inria Paris *) 6 | (* Yann Régis-Gianas, PPS, Université Paris Diderot *) 7 | (* *) 8 | (* Copyright Inria. All rights reserved. This file is distributed under the *) 9 | (* terms of the GNU General Public License version 2, as described in the *) 10 | (* file LICENSE. *) 11 | (* *) 12 | (******************************************************************************) 13 | 14 | include GSet.S with type element = int 15 | -------------------------------------------------------------------------------- /src/ocaml/preprocess/recover/dune: -------------------------------------------------------------------------------- 1 | (executable 2 | (name gen_recover) 3 | (libraries unix menhirSdk)) 4 | -------------------------------------------------------------------------------- /src/ocaml/preprocess/recover/emitter.mli: -------------------------------------------------------------------------------- 1 | open MenhirSdk.Cmly_api 2 | 3 | module Make 4 | (G : GRAMMAR) 5 | (A : Recover_attrib.S with module G = G) 6 | (S : Synthesis.S with module G = G) 7 | (R : Recovery.S with module G = G) : 8 | sig 9 | val emit : Format.formatter -> unit 10 | end 11 | -------------------------------------------------------------------------------- /src/ocaml/preprocess/recover/recover_attrib.mli: -------------------------------------------------------------------------------- 1 | open MenhirSdk 2 | 3 | module type S = sig 4 | module G : Cmly_api.GRAMMAR 5 | 6 | val cost_of_prod : G.production -> float 7 | val penalty_of_item : G.production * int -> float 8 | val cost_of_symbol : G.symbol -> float 9 | 10 | val default_prelude : Format.formatter -> unit 11 | val default_terminal : G.terminal -> string option 12 | val default_nonterminal : G.nonterminal -> string option 13 | end 14 | 15 | module Make (G : Cmly_api.GRAMMAR) : S with module G = G 16 | -------------------------------------------------------------------------------- /src/ocaml/preprocess/recover/recovery.mli: -------------------------------------------------------------------------------- 1 | open MenhirSdk.Cmly_api 2 | module type S = sig 3 | module G : GRAMMAR 4 | 5 | type item = G.lr1 * G.production * int 6 | type recovery = G.lr1 -> int * (G.lr1 option * item list) list 7 | 8 | val recover : recovery 9 | val report : Format.formatter -> unit 10 | end 11 | 12 | module Make (G : GRAMMAR) (S : Synthesis.S with module G = G) : S with module G = G 13 | -------------------------------------------------------------------------------- /src/ocaml/preprocess/recover/synthesis.mli: -------------------------------------------------------------------------------- 1 | open MenhirSdk.Cmly_api 2 | 3 | module type S = sig 4 | module G : GRAMMAR 5 | 6 | type variable = 7 | | Head of G.lr1 * G.nonterminal 8 | | Tail of G.lr1 * G.production * int 9 | 10 | val variable_to_string : variable -> string 11 | 12 | type 'a paction = 13 | | Abort 14 | | Reduce of G.production 15 | | Shift of G.symbol 16 | | Var of 'a 17 | 18 | val paction_to_string : ('a -> string) -> 'a paction -> string 19 | 20 | type action = variable paction 21 | 22 | val action_to_string : action -> string 23 | 24 | val pred : G.lr1 -> G.lr1 list 25 | 26 | val cost_of : variable -> float 27 | val cost_of_action : action -> float 28 | val cost_of_actions : action list -> float 29 | val solution : variable -> action list 30 | val report : Format.formatter -> unit 31 | end 32 | 33 | module Make (G : GRAMMAR) (A : Recover_attrib.S with module G = G) : S with module G = G 34 | -------------------------------------------------------------------------------- /src/ocaml/typing/.ocamlformat-enable: -------------------------------------------------------------------------------- 1 | msupport.ml 2 | msupport.mli 3 | -------------------------------------------------------------------------------- /src/ocaml/typing/dune: -------------------------------------------------------------------------------- 1 | (library 2 | (name ocaml_typing) 3 | (public_name merlin-lib.ocaml_typing) 4 | (flags 5 | -open Ocaml_utils 6 | -open Ocaml_parsing 7 | -open Merlin_utils 8 | (:standard -w -9)) 9 | (modules_without_implementation annot outcometree value_rec_types) 10 | (libraries merlin_utils ocaml_compression ocaml_parsing ocaml_utils)) 11 | -------------------------------------------------------------------------------- /src/ocaml/typing/lambda.ml: -------------------------------------------------------------------------------- 1 | (* The lambda representation is of no interest for Merlin, but some types are 2 | used by [value_rec_check]. *) 3 | 4 | type immediate_or_pointer = 5 | | Immediate 6 | | Pointer 7 | 8 | type array_kind = 9 | Pgenarray | Paddrarray | Pintarray | Pfloatarray 10 | -------------------------------------------------------------------------------- /src/ocaml/typing/saved_parts.ml: -------------------------------------------------------------------------------- 1 | let attribute = Location.mknoloc "merlin.saved-parts" 2 | 3 | module H = Ephemeron.K1.Make(struct 4 | type t = string 5 | let hash = Hashtbl.hash 6 | let equal (a : t) (b : t) = a = b 7 | end) 8 | 9 | let table = H.create 7 10 | 11 | let gensym = 12 | let counter = ref 0 in 13 | fun () -> incr counter; !counter 14 | 15 | let store parts = 16 | let id = string_of_int (gensym ()) in 17 | let key = Parsetree.Pconst_integer (id, None) in 18 | H.add table id parts; 19 | key 20 | 21 | let find = function 22 | | Parsetree.Pconst_integer (id, None) -> 23 | begin 24 | try H.find table id 25 | with Not_found -> [] 26 | end 27 | | _ -> assert false 28 | -------------------------------------------------------------------------------- /src/ocaml/typing/saved_parts.mli: -------------------------------------------------------------------------------- 1 | val attribute : string Location.loc 2 | val store : Cmt_format.binary_part list -> Parsetree.constant_desc 3 | val find : Parsetree.constant_desc -> Cmt_format.binary_part list 4 | -------------------------------------------------------------------------------- /src/ocaml/typing/short_paths.mli: -------------------------------------------------------------------------------- 1 | 2 | module Desc = Short_paths_graph.Desc 3 | 4 | module Basis : sig 5 | 6 | type t 7 | 8 | val create : unit -> t 9 | 10 | val add : t -> string -> unit 11 | 12 | val load : t -> string -> string list -> string list -> 13 | Desc.Module.t -> Desc.deprecated -> unit 14 | 15 | end 16 | 17 | type t 18 | 19 | val initial : Basis.t -> t 20 | 21 | val add : t -> Desc.t list Lazy.t -> t 22 | 23 | type type_result = 24 | | Nth of int 25 | | Path of int list option * Path.t 26 | 27 | val find_type : t -> Path.t -> type_result 28 | 29 | type type_resolution = 30 | | Nth of int 31 | | Subst of int list 32 | | Id 33 | 34 | val find_type_resolution : t -> Path.t -> type_resolution 35 | 36 | val find_type_simple : t -> Path.t -> Path.t 37 | 38 | type class_type_result = int list option * Path.t 39 | 40 | val find_class_type : t -> Path.t -> class_type_result 41 | 42 | val find_class_type_simple : t -> Path.t -> Path.t 43 | 44 | val find_module_type : t -> Path.t -> Path.t 45 | 46 | val find_module : t -> Path.t -> Path.t 47 | -------------------------------------------------------------------------------- /src/ocaml/utils/config.fixed.ml: -------------------------------------------------------------------------------- 1 | <<<<<<< 2 | ======= 3 | let c_output_obj = "" 4 | let c_has_debug_prefix_map = false 5 | let as_has_debug_prefix_map = false 6 | let bytecode_cflags = "" 7 | let bytecode_cppflags = "" 8 | let native_cflags = "" 9 | let native_cppflags = "" 10 | let bytecomp_c_libraries = "" 11 | let bytecomp_c_compiler = "" 12 | let native_c_compiler = c_compiler 13 | >>>>>>> 14 | -------------------------------------------------------------------------------- /src/ocaml/utils/directory_content_cache.ml: -------------------------------------------------------------------------------- 1 | include File_cache.Make (struct 2 | let cache_name = "Directory_content_cache" 3 | type t = string array 4 | 5 | (* For backward compatibility reason, simulate the behavior of 6 | [Misc.find_in_path]: silently ignore directories that don't exist 7 | + treat [""] as the current directory. *) 8 | let read dir = 9 | try 10 | Sys.readdir (if dir = "" then Filename.current_dir_name else dir) 11 | with Sys_error _ -> 12 | [||] 13 | end) 14 | -------------------------------------------------------------------------------- /src/ocaml/utils/dune: -------------------------------------------------------------------------------- 1 | (library 2 | (name ocaml_utils) 3 | (public_name merlin-lib.ocaml_utils) 4 | (libraries merlin_config merlin_utils) 5 | (flags :standard -open Merlin_utils)) 6 | -------------------------------------------------------------------------------- /src/ocaml/utils/lazy_backtrack.mli: -------------------------------------------------------------------------------- 1 | type ('a,'b) t 2 | 3 | type log 4 | 5 | val force : ('a -> 'b) -> ('a,'b) t -> 'b 6 | val create : 'a -> ('a,'b) t 7 | val get_arg : ('a,'b) t -> 'a option 8 | val get_contents : ('a,'b) t -> ('a,'b) Either.t 9 | val create_forced : 'b -> ('a, 'b) t 10 | val create_failed : exn -> ('a, 'b) t 11 | 12 | (* [force_logged log f t] is equivalent to [force f t] but if [f] returns 13 | [None] then [t] is recorded in [log]. [backtrack log] will then reset all 14 | the recorded [t]s back to their original state. *) 15 | val log : unit -> log 16 | val force_logged : 17 | log -> ('a -> ('b, 'c) result) -> ('a,('b, 'c) result) t -> ('b, 'c) result 18 | val backtrack : log -> unit 19 | 20 | (* For compatibility with 4.02 and 4.03 *) 21 | val is_val : ('a, 'b) t -> bool 22 | type ('a, 'b) eval = 23 | | Done of 'b 24 | | Raise of exn 25 | | Thunk of 'a 26 | val view : ('a, 'b) t -> ('a, 'b) eval 27 | 28 | (* For compatibility with 4.08 and 4.09 *) 29 | val force_logged_408 : 30 | log -> ('a -> 'b option) -> ('a,'b option) t -> 'b option 31 | -------------------------------------------------------------------------------- /src/platform/dune: -------------------------------------------------------------------------------- 1 | (library 2 | (name os_ipc) 3 | (public_name merlin-lib.os_ipc) 4 | (foreign_stubs (language c) (names os_ipc_stub))) 5 | -------------------------------------------------------------------------------- /src/platform/os_ipc.ml: -------------------------------------------------------------------------------- 1 | type server 2 | type context 3 | 4 | type client = 5 | { context : context; wd : string; environ : string; argv : string array } 6 | 7 | (* {1 Server management} 8 | Listen, accept client and close *) 9 | 10 | external server_setup : string -> string -> server option 11 | = "ml_merlin_server_setup" 12 | 13 | external server_accept : server -> timeout:float -> client option 14 | = "ml_merlin_server_accept" 15 | 16 | external server_close : server -> unit = "ml_merlin_server_close" 17 | 18 | (* {1 Context management (stdin, stdout, stderr)} 19 | Setup and close *) 20 | 21 | external context_setup : context -> unit = "ml_merlin_context_setup" 22 | 23 | external context_close : context -> return_code:int -> unit 24 | = "ml_merlin_context_close" 25 | 26 | (* {1 Environment management} *) 27 | 28 | (** completely replace the environment *) 29 | external merlin_set_environ : string -> unit = "ml_merlin_set_environ" 30 | 31 | (* {1 Fixup for Windows process management} *) 32 | 33 | external merlin_dont_inherit_stdio : bool -> unit 34 | = "ml_merlin_dont_inherit_stdio" 35 | -------------------------------------------------------------------------------- /src/sherlodoc/.ocamlformat-ignore: -------------------------------------------------------------------------------- 1 | type_parser.ml 2 | type_parser.mli 3 | -------------------------------------------------------------------------------- /src/sherlodoc/dune: -------------------------------------------------------------------------------- 1 | (library 2 | (name merlin_sherlodoc) 3 | (public_name merlin-lib.sherlodoc)) 4 | 5 | (menhir 6 | (modules type_parser) 7 | (enabled_if (<> %{profile} "release")) 8 | (mode promote) 9 | (flags :standard --explain)) 10 | 11 | (ocamllex type_lexer) 12 | -------------------------------------------------------------------------------- /src/sherlodoc/type_lexer.mll: -------------------------------------------------------------------------------- 1 | { 2 | open Type_parser 3 | } 4 | 5 | rule token = parse 6 | | ' ' { token lexbuf } 7 | | "->" { ARROW } 8 | | "(" { PARENS_OPEN } 9 | | ")" { PARENS_CLOSE } 10 | | "," { COMMA } 11 | | '_' { WILDCARD } 12 | | '*' { STAR } 13 | | "'" (['a'-'z' 'A'-'Z' '0'-'9' '\'' '_']* as p) { POLY p } 14 | | ['a'-'z' 'A'-'Z' '0'-'9' '\'' '_' '.']+ as w { WORD w } 15 | | eof { EOF } -------------------------------------------------------------------------------- /src/sherlodoc/type_parser.mli: -------------------------------------------------------------------------------- 1 | 2 | (* The type of tokens. *) 3 | 4 | type token = 5 | | WORD of (string) 6 | | WILDCARD 7 | | STAR 8 | | POLY of (string) 9 | | PARENS_OPEN 10 | | PARENS_CLOSE 11 | | EOF 12 | | COMMA 13 | | ARROW 14 | 15 | (* This exception is raised by the monolithic API functions. *) 16 | 17 | exception Error 18 | 19 | (* The monolithic API. *) 20 | 21 | val main: (Lexing.lexbuf -> token) -> Lexing.lexbuf -> (Type_parsed.t) 22 | -------------------------------------------------------------------------------- /src/sherlodoc/type_parser.mly: -------------------------------------------------------------------------------- 1 | %token EOF 2 | %token PARENS_OPEN PARENS_CLOSE 3 | %token ARROW COMMA WILDCARD STAR 4 | %token WORD 5 | %token POLY 6 | 7 | %start main 8 | %type main 9 | 10 | %% 11 | 12 | main: 13 | | t=typ EOF { t } 14 | ; 15 | 16 | typ: 17 | | t=typ2 { t } 18 | | a=typ2 ARROW b=typ { Type_parsed.Arrow (a, b) } 19 | ; 20 | 21 | typ2: 22 | | xs=list1(typ1, STAR) { Type_parsed.tuple xs } 23 | ; 24 | 25 | typ1: 26 | | { Type_parsed.Wildcard } 27 | | ts=typs { Type_parsed.tuple ts } 28 | | ts=typs w=WORD ws=list(WORD) 29 | { 30 | List.fold_left ( fun acc w -> 31 | Type_parsed.Tycon (w, [acc])) (Type_parsed.Tycon (w, ts)) ws 32 | } 33 | ; 34 | 35 | typ0: 36 | | WILDCARD { Type_parsed.Wildcard } 37 | | w=POLY { Type_parsed.Tyvar w } 38 | | w=WORD { Type_parsed.Tycon (w, []) } 39 | ; 40 | 41 | 42 | typs: 43 | | t=typ0 { [t] } 44 | | PARENS_OPEN ts=list1(typ, COMMA) PARENS_CLOSE { ts } 45 | ; 46 | 47 | 48 | list1(term, separator): 49 | | x=term { [x] } 50 | | x=term separator xs=list1(term, separator) { x::xs } 51 | ; 52 | 53 | -------------------------------------------------------------------------------- /src/utils/.ocamlformat-ignore: -------------------------------------------------------------------------------- 1 | format_doc.ml 2 | format_doc.mli 3 | misc.ml 4 | misc.mli 5 | stamped_hashtable.ml 6 | stamped_hashtable.mli 7 | -------------------------------------------------------------------------------- /src/utils/dune: -------------------------------------------------------------------------------- 1 | (rule (copy# ../platform/platform_misc.c platform_misc.c)) 2 | 3 | (library 4 | (name merlin_utils) 5 | (public_name merlin-lib.utils) 6 | (libraries str unix) 7 | (foreign_stubs (language c) (names platform_misc))) 8 | -------------------------------------------------------------------------------- /src/utils/file_id.mli: -------------------------------------------------------------------------------- 1 | (** An instance of [t] represents the identity of the contents of a file path. 2 | Use this to quickly detect if a file has changed. 3 | (Detection is done by checking some fields from stat syscall, 4 | it can be tricked but should behave well in regular cases). 5 | FIXME: precision of mtime is still the second?! 6 | *) 7 | type t 8 | 9 | (** Returns true iff the heuristic determines that the file contents has not 10 | changed. *) 11 | val check : t -> t -> bool 12 | 13 | (** [file_id filename] computes an id for the current contents of [filename]. 14 | Returns a generic id, if the id can't be computed. *) 15 | val get : string -> t 16 | 17 | (** Same as [get], but returns an error, if the id can't be computed. *) 18 | val get_res : string -> (t, string) Result.t 19 | 20 | val with_cache : (unit -> 'a) -> 'a 21 | -------------------------------------------------------------------------------- /src/utils/lib_config.ml: -------------------------------------------------------------------------------- 1 | let program_name = ref "Merlin" 2 | 3 | let set_program_name name = program_name := name 4 | 5 | let program_name () = !program_name 6 | 7 | module Json = struct 8 | let set_pretty_to_string f = Std.Json.pretty_to_string := f 9 | end 10 | 11 | module System = struct 12 | let set_run_in_directory f = Std.System.run_in_directory := f 13 | end 14 | -------------------------------------------------------------------------------- /src/utils/sexp.mli: -------------------------------------------------------------------------------- 1 | open Std 2 | 3 | type t = 4 | | Cons of t * t 5 | | Sym of string 6 | | String of string 7 | | Int of int 8 | | Float of float 9 | 10 | val nil : t 11 | val of_list : t list -> t 12 | 13 | val tell_sexp : (string -> unit) -> t -> unit 14 | val tell_cons : (string -> unit) -> t -> unit 15 | 16 | val to_buf : t -> Buffer.t -> unit 17 | 18 | val to_string : t -> string 19 | 20 | val of_string : string -> t 21 | 22 | val of_file_descr : 23 | ?on_read:(Unix.file_descr -> unit) -> Unix.file_descr -> unit -> t option 24 | val of_channel : 25 | ?on_read:(Unix.file_descr -> unit) -> in_channel -> unit -> t option 26 | 27 | val of_json : json -> t 28 | val to_json : t -> json 29 | -------------------------------------------------------------------------------- /tests/dune: -------------------------------------------------------------------------------- 1 | (env 2 | (_ 3 | (binaries merlin-wrapper) 4 | (env-vars 5 | (MERLIN merlin-wrapper) 6 | (OCAMLC ocamlc) 7 | (DUNE dune)))) 8 | 9 | (cram 10 | (package merlin) 11 | (applies_to :whole_subtree) 12 | (deps 13 | %{bin:merlin-wrapper} 14 | %{bin:ocamlmerlin-server} 15 | %{bin:ocamlmerlin} 16 | %{bin:dot-merlin-reader})) 17 | 18 | (cram 19 | (applies_to with-ppx) 20 | (deps 21 | (package ppxlib))) 22 | -------------------------------------------------------------------------------- /tests/merlin-wrapper: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | export PATH=$(dirname dot-merlin-reader):$PATH 4 | 5 | # If no dune-project of .merlin file are present in the test we write a default 6 | # `.merlin` file to force the use of dot-merlin-reader 7 | if [ ! -f dune-project ]; then 8 | touch .merlin 9 | fi 10 | 11 | ocamlmerlin "$@" \ 12 | | jq 'del(.timing)' \ 13 | | jq 'del(.heap_mbytes)' \ 14 | | jq 'del(.cache)' \ 15 | | jq 'del(.query_num)' \ 16 | | sed -e 's:"[^"]*lib/ocaml:"lib/ocaml:g' \ 17 | | sed -e 's:\\n:\ 18 | :g' 19 | -------------------------------------------------------------------------------- /tests/test-dirs/.merlin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ocaml/merlin/754ec9eacf5b4fd6525a16609a2406175d59013e/tests/test-dirs/.merlin -------------------------------------------------------------------------------- /tests/test-dirs/alerts.t/lib.mli: -------------------------------------------------------------------------------- 1 | val sqrt : float -> float 2 | [@@ocaml.deprecated "I am deprecated"] 3 | -------------------------------------------------------------------------------- /tests/test-dirs/alerts.t/main.ml: -------------------------------------------------------------------------------- 1 | open Lib 2 | let x = sqrt 3. 3 | -------------------------------------------------------------------------------- /tests/test-dirs/completion/application_context.t/application_context.ml: -------------------------------------------------------------------------------- 1 | let foo ~i ~j = i + j 2 | let bar = 10 3 | let y = foo ~i:5 4 | -------------------------------------------------------------------------------- /tests/test-dirs/completion/application_context.t/run.t: -------------------------------------------------------------------------------- 1 | $ $MERLIN single complete-prefix -position 3:17 \ 2 | > -filename application_context < application_context.ml \ 3 | > | tr '\n' ' ' | jq ".value.context" 4 | [ 5 | "application", 6 | { 7 | "argument_type": "'a", 8 | "labels": [ 9 | { 10 | "name": "~j", 11 | "type": "int" 12 | } 13 | ] 14 | } 15 | ] 16 | -------------------------------------------------------------------------------- /tests/test-dirs/completion/disambiguation.t/constr.ml: -------------------------------------------------------------------------------- 1 | module T = struct 2 | type t = Foobar 3 | end 4 | 5 | let _foobar = (Foo : T.t) 6 | -------------------------------------------------------------------------------- /tests/test-dirs/completion/disambiguation.t/record.ml: -------------------------------------------------------------------------------- 1 | module T = struct 2 | type t = { foobar : int; test_other : float; } 3 | end 4 | 5 | let _easy = { T.f } 6 | 7 | let _hard = ({ foo } : T.t) 8 | 9 | open T 10 | 11 | let _easier = { foobar = 5; tes } 12 | -------------------------------------------------------------------------------- /tests/test-dirs/completion/dune: -------------------------------------------------------------------------------- 1 | (cram 2 | (applies_to issue1575) 3 | (enabled_if 4 | (<> %{os_type} Win32))) 5 | -------------------------------------------------------------------------------- /tests/test-dirs/completion/expansion.t/expansion1.ml: -------------------------------------------------------------------------------- 1 | let x = L.m 2 | -------------------------------------------------------------------------------- /tests/test-dirs/completion/expansion.t/expansion2.ml: -------------------------------------------------------------------------------- 1 | let x = Lsi.m 2 | -------------------------------------------------------------------------------- /tests/test-dirs/completion/infix.t/infix.ml: -------------------------------------------------------------------------------- 1 | module Z = struct 2 | let (>>) = 0 3 | let (|+) = 0 4 | let (|-) = 0 5 | let (>>=) = 0 6 | let (>>|) = 0 7 | end 8 | 9 | let _ = Z. 10 | -------------------------------------------------------------------------------- /tests/test-dirs/completion/infix.t/run.t: -------------------------------------------------------------------------------- 1 | $ $MERLIN single complete-prefix -position 11:10 -prefix "Z." \ 2 | > -filename infix.ml < infix.ml | jq ".value.entries | sort_by(.name)" 3 | [ 4 | { 5 | "name": "(>>)", 6 | "kind": "Value", 7 | "desc": "int", 8 | "info": "", 9 | "deprecated": false 10 | }, 11 | { 12 | "name": "(>>=)", 13 | "kind": "Value", 14 | "desc": "int", 15 | "info": "", 16 | "deprecated": false 17 | }, 18 | { 19 | "name": "(>>|)", 20 | "kind": "Value", 21 | "desc": "int", 22 | "info": "", 23 | "deprecated": false 24 | }, 25 | { 26 | "name": "(|+)", 27 | "kind": "Value", 28 | "desc": "int", 29 | "info": "", 30 | "deprecated": false 31 | }, 32 | { 33 | "name": "(|-)", 34 | "kind": "Value", 35 | "desc": "int", 36 | "info": "", 37 | "deprecated": false 38 | } 39 | ] 40 | -------------------------------------------------------------------------------- /tests/test-dirs/completion/issue-lsp-503.t: -------------------------------------------------------------------------------- 1 | 2 | $ cat >test.ml <<'EOF' 3 | > [1;2]|>List.ma 4 | > EOF 5 | 6 | We complete the name of the object 7 | 8 | $ $MERLIN single complete-prefix -position 1:14 -prefix "List.ma" \ 9 | > -filename test.ml < test.ml 10 | { 11 | "class": "return", 12 | "value": { 13 | "entries": [ 14 | { 15 | "name": "map", 16 | "kind": "Value", 17 | "desc": "('a -> 'b) -> 'a list -> 'b list", 18 | "info": "", 19 | "deprecated": false 20 | }, 21 | { 22 | "name": "mapi", 23 | "kind": "Value", 24 | "desc": "(int -> 'a -> 'b) -> 'a list -> 'b list", 25 | "info": "", 26 | "deprecated": false 27 | }, 28 | { 29 | "name": "map2", 30 | "kind": "Value", 31 | "desc": "('a -> 'b -> 'c) -> 'a list -> 'b list -> 'c list", 32 | "info": "", 33 | "deprecated": false 34 | } 35 | ], 36 | "context": null 37 | }, 38 | "notifications": [] 39 | } 40 | -------------------------------------------------------------------------------- /tests/test-dirs/completion/kind.t/test.ml: -------------------------------------------------------------------------------- 1 | let funnyny = fun ny -> ny 2 | 3 | let _ = fu 4 | 5 | let _ = List.f 6 | -------------------------------------------------------------------------------- /tests/test-dirs/completion/parenthesize.t/parenthesize.ml: -------------------------------------------------------------------------------- 1 | module MyList = struct 2 | [@@@ocaml.warning "-65"] 3 | type 'a t = 4 | | (::) of 'a * 'a t 5 | | [] 6 | type u = () 7 | let (mod) = () 8 | let random = 1 9 | end 10 | 11 | let _ = MyList. 12 | -------------------------------------------------------------------------------- /tests/test-dirs/config/check/check-config.t: -------------------------------------------------------------------------------- 1 | Create a .merlin: 2 | 3 | $ cat > .merlin < S ../../../../src/frontend 5 | > EOF 6 | 7 | $ echo | $MERLIN single check-configuration -filename test.ml 8 | { 9 | "class": "return", 10 | "value": { 11 | "dot_merlins": [ 12 | "$TESTCASE_ROOT/.merlin" 13 | ], 14 | "failures": [] 15 | }, 16 | "notifications": [] 17 | } 18 | -------------------------------------------------------------------------------- /tests/test-dirs/config/check/dune: -------------------------------------------------------------------------------- 1 | (cram 2 | (applies_to check-config) 3 | (enabled_if 4 | (<> %{os_type} Win32))) 5 | -------------------------------------------------------------------------------- /tests/test-dirs/config/dot-merlin-reader/dune: -------------------------------------------------------------------------------- 1 | (cram 2 | (applies_to erroneous-config quoting load-config) 3 | (enabled_if 4 | (<> %{os_type} Win32))) 5 | -------------------------------------------------------------------------------- /tests/test-dirs/config/dot-merlin-reader/erroneous-config.t: -------------------------------------------------------------------------------- 1 | Create a broke .merlin: 2 | 3 | $ cat > .merlin < FLG -principal 5 | > PKG does-not-exist 6 | > # some comment 7 | > EOF 8 | 9 | And look at merlin's config: 10 | 11 | $ echo | $MERLIN single dump-configuration -filename test.ml | \ 12 | > jq ".value.merlin | {flags_applied: .flags_applied, failures: .failures}" 13 | { 14 | "flags_applied": [ 15 | { 16 | "workdir": "$TESTCASE_ROOT", 17 | "workval": [ 18 | "-principal" 19 | ] 20 | } 21 | ], 22 | "failures": [ 23 | "Failed to load packages: does-not-exist" 24 | ] 25 | } 26 | 27 | Also, see that the failure is reported to the user: 28 | 29 | $ echo | $MERLIN single errors -filename test.ml 30 | { 31 | "class": "return", 32 | "value": [ 33 | { 34 | "type": "config", 35 | "sub": [], 36 | "valid": true, 37 | "message": "Failed to load packages: does-not-exist" 38 | } 39 | ], 40 | "notifications": [] 41 | } 42 | 43 | $ rm .merlin 44 | -------------------------------------------------------------------------------- /tests/test-dirs/config/dot-merlin-reader/stdlib-config.t: -------------------------------------------------------------------------------- 1 | The STDLIB directive in .merlin is respected 2 | $ cat > .merlin < STDLIB /stdlib1 4 | > EOF 5 | 6 | $ echo | $MERLIN single dump-configuration -filename test.ml 2> /dev/null | jq '.value.merlin.stdlib' 7 | "/stdlib1" 8 | 9 | $ rm .merlin 10 | 11 | The -ocamlib-path flag is respected 12 | $ echo | $MERLIN single dump-configuration -ocamllib-path /stdlib2 -filename test.ml 2> /dev/null | jq '.value.merlin.stdlib' 13 | "/stdlib2" 14 | 15 | The STDLIB directive in .merlin takes priority over -ocamllib-path 16 | $ cat > .merlin < STDLIB /stdlib-from-.merlin 18 | > EOF 19 | 20 | $ echo | $MERLIN single dump-configuration -ocamllib-path /stdlib-from-flag -filename test.ml 2> /dev/null | jq '.value.merlin.stdlib' 21 | "/stdlib-from-.merlin" 22 | -------------------------------------------------------------------------------- /tests/test-dirs/config/dune: -------------------------------------------------------------------------------- 1 | (cram 2 | (applies_to path-expansion hidden-deps exclude-query-dir) 3 | (enabled_if 4 | (<> %{os_type} Win32))) 5 | 6 | (cram 7 | (applies_to symlinks workdir) 8 | (enabled_if false)) 9 | -------------------------------------------------------------------------------- /tests/test-dirs/config/exclude-query-dir.t: -------------------------------------------------------------------------------- 1 | Test the EXCLUDE_QUERY_DIR directive, which tells Merlin not to look for build artifacts 2 | in the directory of the file being queried on. To test, we create a/test.ml, which depends 3 | on b/foo.ml. The folder b contains a .cmt for the Foo module, and Merlin is configured to 4 | look there. We also include a malformatted foo.cmt in the query directory. 5 | $ mkdir a 6 | $ mkdir b 7 | 8 | $ cat > a/test.ml << EOF 9 | > let x = Foo.bar 10 | > EOF 11 | 12 | $ cat > b/foo.ml << EOF 13 | > let bar = 10 14 | > EOF 15 | 16 | Create the proper and malformatted .cmt files 17 | $ $OCAMLC -c -bin-annot b/foo.ml 18 | $ touch a/foo.cmt 19 | 20 | Configure Merlin 21 | $ cat > a/.merlin << EOF 22 | > S . 23 | > B ../b 24 | > S ../b 25 | > EXCLUDE_QUERY_DIR 26 | > EOF 27 | 28 | Perform the query 29 | $ $MERLIN single locate -position 1:13 -filename a/test.ml < a/test.ml 30 | { 31 | "class": "return", 32 | "value": { 33 | "file": "$TESTCASE_ROOT/b/foo.ml", 34 | "pos": { 35 | "line": 1, 36 | "col": 4 37 | } 38 | }, 39 | "notifications": [] 40 | } 41 | -------------------------------------------------------------------------------- /tests/test-dirs/config/flags/dune: -------------------------------------------------------------------------------- 1 | (cram 2 | (applies_to invalid) 3 | (enabled_if 4 | (<> %{os_type} Win32))) 5 | -------------------------------------------------------------------------------- /tests/test-dirs/config/flags/invalid.t: -------------------------------------------------------------------------------- 1 | $ echo | $MERLIN single check-configuration -filename invalid_flag.ml -lalala 2 | { 3 | "class": "return", 4 | "value": { 5 | "dot_merlins": [ 6 | "$TESTCASE_ROOT/.merlin" 7 | ], 8 | "failures": [ 9 | "unknown flag -lalala" 10 | ] 11 | }, 12 | "notifications": [] 13 | } 14 | -------------------------------------------------------------------------------- /tests/test-dirs/config/flags/nolabels.t: -------------------------------------------------------------------------------- 1 | classic and labels 2 | 3 | $ $MERLIN single errors -filename labels_ok_1.ml < let f ~x = () in f ~x:(); f () 5 | > EOF 6 | { 7 | "class": "return", 8 | "value": [ 9 | { 10 | "start": { 11 | "line": 1, 12 | "col": 26 13 | }, 14 | "end": { 15 | "line": 1, 16 | "col": 27 17 | }, 18 | "type": "warning", 19 | "sub": [], 20 | "valid": true, 21 | "message": "Warning 6: label x was omitted in the application of this function." 22 | } 23 | ], 24 | "notifications": [] 25 | } 26 | 27 | $ $MERLIN single errors -filename labels_ko_1.ml -nolabels < let f ~x = () in f ~x:(); f () 29 | > EOF 30 | { 31 | "class": "return", 32 | "value": [], 33 | "notifications": [] 34 | } 35 | -------------------------------------------------------------------------------- /tests/test-dirs/config/no-dune.t: -------------------------------------------------------------------------------- 1 | $ mkdir bin 2 | $ cp ../../../../install/default/bin/ocamlmerlin bin/ocamlmerlin 3 | $ cp ../../../../install/default/bin/ocamlmerlin-server bin/ocamlmerlin-server 4 | 5 | $ cat >dune-project < (lang dune 2.0) 7 | > EOF 8 | 9 | $ cat >main.ml < print_endline "Hello world" 11 | > EOF 12 | 13 | $ PATH=bin ocamlmerlin single dump-configuration \ 14 | > -filename main.ml output 15 | 16 | $ cat output | jq '.value.merlin.failures' 17 | [ 18 | "Merlin could not find `dune` in the PATH to get project configuration. If you do not rely on Dune, make sure `.merlin` files are present in the project's sources." 19 | ] 20 | 21 | $ cat >.merlin < S . 23 | > EOF 24 | 25 | $ PATH=bin ocamlmerlin single dump-configuration \ 26 | > -filename main.ml output 27 | 28 | $ cat output | jq '.value.merlin.failures' 29 | [ 30 | "Merlin could not find `dot-merlin-reader` in the PATH. Please make sure that `dot-merlin-reader` is installed and in the PATH." 31 | ] 32 | -------------------------------------------------------------------------------- /tests/test-dirs/config/path-expansion.t/run.t: -------------------------------------------------------------------------------- 1 | A simple name is not expanded 2 | 3 | $ echo | $MERLIN single dump-configuration -filename relative_path.ml -ppx test1 \ 4 | > 2> /dev/null | \ 5 | > jq '.value.ocaml.ppx' 6 | [ 7 | { 8 | "workdir": "$TESTCASE_ROOT", 9 | "workval": "test1" 10 | } 11 | ] 12 | 13 | Neither is an absolute path 14 | 15 | $ echo | $MERLIN single dump-configuration -filename relative_path.ml -ppx /test2 \ 16 | > 2> /dev/null | \ 17 | > jq '.value.ocaml.ppx' 18 | [ 19 | { 20 | "workdir": "$TESTCASE_ROOT", 21 | "workval": "/test2" 22 | } 23 | ] 24 | 25 | But relative names are 26 | 27 | $ echo | $MERLIN single dump-configuration -filename relative_path.ml -ppx ./test3 \ 28 | > 2> /dev/null | \ 29 | > jq '.value.ocaml.ppx' 30 | [ 31 | { 32 | "workdir": "$TESTCASE_ROOT", 33 | "workval": "./test3" 34 | } 35 | ] 36 | -------------------------------------------------------------------------------- /tests/test-dirs/config/symlinks.t/real/main.ml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ocaml/merlin/754ec9eacf5b4fd6525a16609a2406175d59013e/tests/test-dirs/config/symlinks.t/real/main.ml -------------------------------------------------------------------------------- /tests/test-dirs/config/unknown_tag.t: -------------------------------------------------------------------------------- 1 | $ cat >.merlin < B foobar_dir 3 | > FOOBAR bar 4 | > EOF 5 | 6 | $ $MERLIN single errors -filename test.ml < let x = 2 8 | > EOF 9 | { 10 | "class": "return", 11 | "value": [ 12 | { 13 | "type": "config", 14 | "sub": [], 15 | "valid": true, 16 | "message": "Unknown tag in .merlin: FOOBAR" 17 | } 18 | ], 19 | "notifications": [] 20 | } 21 | -------------------------------------------------------------------------------- /tests/test-dirs/config/workdir.t/src/main.ml: -------------------------------------------------------------------------------- 1 | print_string "foobar" 2 | -------------------------------------------------------------------------------- /tests/test-dirs/construct/c-inline-record-issue1617.t: -------------------------------------------------------------------------------- 1 | $ cat >main.ml < type foo_record = { foo : int } 3 | > 4 | > type foo = Foo of foo_record 5 | > type bar = Bar of { bar : int } 6 | > 7 | > let x : foo = _ (* succeeds *) 8 | > let y : bar = _ (* fails *) 9 | > EOF 10 | 11 | $ $MERLIN single construct -position 6:15 \ 12 | > -filename main.ml -filename main.ml 'b) 4 | type t2 = A | B of string | C of t 5 | type nonrec r = { lbl1 : t; lbl2 : float list} 6 | type nonrec n = r and m = float 7 | type t_ext = .. 8 | type t_ext += Str of string | A 9 | type v = [`A of t_ext] 10 | 11 | val i : int 12 | val f : t -> int 13 | 14 | module Sub : sig 15 | val y : int 16 | end 17 | 18 | class type room = object 19 | val mutable gene : unit 20 | 21 | method scientific : unit -> int 22 | end 23 | class croom : room 24 | module type Another = sig val i : int end 25 | 26 | module type Sig = sig 27 | type t and b 28 | val f : int -> float 29 | module type STyp = sig end 30 | module D : Another 31 | end 32 | 33 | module Submod : Sig 34 | 35 | module SubFunc (M : Sig) : sig val g : unit end 36 | end 37 | 38 | module type Small = sig type t = int end 39 | 40 | module M : S = _ 41 | 42 | let m : (module Small) = _ 43 | 44 | let m = (module _ : Small) 45 | -------------------------------------------------------------------------------- /tests/test-dirs/construct/c-parenthesis.t: -------------------------------------------------------------------------------- 1 | ############### 2 | ## SUM TYPES ## 3 | ############### 4 | 5 | Test 1.1 : 6 | 7 | $ cat >c1.ml < let x : int option option = Some (_) 9 | > EOF 10 | 11 | $ $MERLIN single construct -position 1:34 \ 12 | > -filename c1.ml int 3 | [@@ocaml.deprecated "deprecation message"] 4 | 5 | val baz : unit -> unit 6 | -------------------------------------------------------------------------------- /tests/test-dirs/deprecation.t/run.t: -------------------------------------------------------------------------------- 1 | $ echo "S .\nB .\nFLG -nopervasives" > .merlin 2 | $ $OCAMLC -nopervasives -c -bin-annot foo.mli 3 | $ $MERLIN single complete-prefix -position 2:14 -prefix Foo.ba -kind val -filename x.ml < x.ml 4 | { 5 | "class": "return", 6 | "value": { 7 | "entries": [ 8 | { 9 | "name": "bar", 10 | "kind": "Value", 11 | "desc": "unit -> int", 12 | "info": "", 13 | "deprecated": true 14 | }, 15 | { 16 | "name": "baz", 17 | "kind": "Value", 18 | "desc": "unit -> unit", 19 | "info": "", 20 | "deprecated": false 21 | } 22 | ], 23 | "context": null 24 | }, 25 | "notifications": [] 26 | } 27 | -------------------------------------------------------------------------------- /tests/test-dirs/deprecation.t/x.ml: -------------------------------------------------------------------------------- 1 | let x = Foo.ba 2 | -------------------------------------------------------------------------------- /tests/test-dirs/destruct/dune: -------------------------------------------------------------------------------- 1 | (cram 2 | (applies_to :whole_subtree) 3 | (alias all-destruct-tests)) 4 | -------------------------------------------------------------------------------- /tests/test-dirs/destruct/issue1601.t: -------------------------------------------------------------------------------- 1 | $ cat >main.ml < let foo : [< \`Foo ] option = None 3 | > 4 | > let () = 5 | > match foo with 6 | > | None | Some _ -> () 7 | > EOF 8 | 9 | $ $MERLIN single case-analysis -start 5:16 -end 5:16 \ 10 | > -filename main.ml jq '.value[1]' 12 | "`Foo" 13 | 14 | $ cat >main.ml < let foo : [> \`Foo ] option = None 16 | > 17 | > let () = 18 | > match foo with 19 | > | None | Some _ -> () 20 | > EOF 21 | 22 | $ $MERLIN single case-analysis -start 5:16 -end 5:16 \ 23 | > -filename main.ml jq '.value[1]' 25 | "`Foo" 26 | 27 | $ cat >main.ml < let foo : [< \`Foo | \`Bar > \`Foo] option = None 29 | > 30 | > let () = 31 | > match foo with 32 | > | None | Some _ -> () 33 | > EOF 34 | 35 | $ $MERLIN single case-analysis -start 5:16 -end 5:16 \ 36 | > -filename main.ml jq '.value[1]' 38 | "None | Some `Bar | Some `Foo" 39 | -------------------------------------------------------------------------------- /tests/test-dirs/destruct/issue1661.t: -------------------------------------------------------------------------------- 1 | $ $MERLIN single case-analysis -start 2:9 -end 2:9 \ 2 | > -filename main.ml < type t = {a: int * int; b: string} 4 | > let f ({a; b} : t) = assert false 5 | > EOF 6 | { 7 | "class": "return", 8 | "value": [ 9 | { 10 | "start": { 11 | "line": 2, 12 | "col": 8 13 | }, 14 | "end": { 15 | "line": 2, 16 | "col": 9 17 | } 18 | }, 19 | "a = (_, _)" 20 | ], 21 | "notifications": [] 22 | } 23 | 24 | 25 | $ $MERLIN single case-analysis -start 2:9 -end 2:9 \ 26 | > -filename main.ml < type t = {a: int option; b: string} 28 | > let f ({a; b} : t) = assert false 29 | > EOF 30 | { 31 | "class": "return", 32 | "value": [ 33 | { 34 | "start": { 35 | "line": 2, 36 | "col": 7 37 | }, 38 | "end": { 39 | "line": 2, 40 | "col": 13 41 | } 42 | }, 43 | "({ a = None; b } : t) | ({ a = Some _; b } : t)" 44 | ], 45 | "notifications": [] 46 | } 47 | -------------------------------------------------------------------------------- /tests/test-dirs/destruct/issue596.t: -------------------------------------------------------------------------------- 1 | $ $MERLIN single case-analysis -start 1:5 -end 1:5 -filename bug.ml < let a = 1 in a + 1 ;; 3 | > EOF 4 | { 5 | "class": "error", 6 | "value": "Destruct not allowed on value_binding", 7 | "notifications": [] 8 | } 9 | -------------------------------------------------------------------------------- /tests/test-dirs/document/dune: -------------------------------------------------------------------------------- 1 | (cram 2 | (applies_to src-documentation module-doc) 3 | (enabled_if (<> %{architecture} i386))) 4 | -------------------------------------------------------------------------------- /tests/test-dirs/document/external-pattern-comments.t: -------------------------------------------------------------------------------- 1 | $ cat >main.ml < let _ = Lib.y 3 | > EOF 4 | 5 | $ cat >lib.ml < (** doc for all node *) 7 | > let x, y = 2, 3 8 | > EOF 9 | 10 | $ $OCAMLC -c -bin-annot lib.ml main.ml 11 | 12 | $ $MERLIN single document -position 1:12 \ 13 | > -log-file - 2>log \ 14 | > -filename main.ml doc.ml < (** whatever *) 3 | > let id () = () 4 | > let _ = id () 5 | > EOF 6 | 7 | $ $MERLIN single document -position 2:5 \ 8 | > -filename doc.ml -filename doc.ml test.ml < let foo x y = (** incorrect doc for foo *) 6 | > x + y 7 | > 8 | > let bar = foo 9 | > EOF 10 | 11 | $ $MERLIN single document -position 4:13 -filename test.ml < test.ml 12 | { 13 | "class": "return", 14 | "value": "incorrect doc for foo", 15 | "notifications": [] 16 | } 17 | 18 | And that it also works outside of the current buffer: 19 | 20 | $ $OCAMLC -c -bin-annot -w +50 test.ml 21 | File "test.ml", line 1, characters 14-42: 22 | 1 | let foo x y = (** incorrect doc for foo *) 23 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 24 | Warning 50 [unexpected-docstring]: unattached documentation comment (ignored) 25 | 26 | $ $MERLIN single document -position 1:18 -filename outside.ml << EOF 27 | > let bar = Test.foo 28 | > EOF 29 | { 30 | "class": "return", 31 | "value": "incorrect doc for foo", 32 | "notifications": [] 33 | } 34 | -------------------------------------------------------------------------------- /tests/test-dirs/dune: -------------------------------------------------------------------------------- 1 | (cram 2 | (applies_to no-escape type-expr environment_on_open locate-type 3 | polarity-search issue1900) 4 | (enabled_if 5 | (<> %{os_type} Win32))) 6 | 7 | (cram 8 | (applies_to typing-recovery) 9 | (enabled_if 10 | (and 11 | (<> %{ocaml_version} 4.12.0+multicore) 12 | (<> %{ocaml_version} 4.12.0+domains)))) 13 | 14 | -------------------------------------------------------------------------------- /tests/test-dirs/environment_on_open.t/environment_on_open.ml: -------------------------------------------------------------------------------- 1 | module M = struct 2 | (* should jump above this comment, 3 | but jumps below it pre 4.08 *) 4 | module M = struct end 5 | end 6 | open M 7 | -------------------------------------------------------------------------------- /tests/test-dirs/environment_on_open.t/run.t: -------------------------------------------------------------------------------- 1 | $ $MERLIN single locate -look-for ml -position 6:6 \ 2 | > -filename ./environment_on_open.ml < ./environment_on_open.ml 3 | { 4 | "class": "return", 5 | "value": { 6 | "file": "$TESTCASE_ROOT/environment_on_open.ml", 7 | "pos": { 8 | "line": 1, 9 | "col": 7 10 | } 11 | }, 12 | "notifications": [] 13 | } 14 | -------------------------------------------------------------------------------- /tests/test-dirs/errors/error-in-constrained-env.t/run.t: -------------------------------------------------------------------------------- 1 | In the example, typing "None" will fail. 2 | Because the environment has constraints, the failure will happen between a 3 | begin_def and an end_def. 4 | Thus the error recovery will happen at the wrong level. 5 | The fix is to save and restore levels when attempting a recoverable typing. 6 | 7 | $ $MERLIN single errors -filename test.ml < test.ml 8 | { 9 | "class": "return", 10 | "value": [ 11 | { 12 | "start": { 13 | "line": 7, 14 | "col": 9 15 | }, 16 | "end": { 17 | "line": 7, 18 | "col": 13 19 | }, 20 | "type": "typer", 21 | "sub": [], 22 | "valid": true, 23 | "message": "This expression should not be a constructor, the expected type is a -> string" 24 | } 25 | ], 26 | "notifications": [] 27 | } 28 | -------------------------------------------------------------------------------- /tests/test-dirs/errors/error-in-constrained-env.t/test.ml: -------------------------------------------------------------------------------- 1 | type _ gadt = 2 | | I : int gadt 3 | | S : string gadt 4 | 5 | let show : type a. a gadt -> a -> string = function 6 | | I -> string_of_int 7 | | S -> None 8 | -------------------------------------------------------------------------------- /tests/test-dirs/errors/error-node-line-break.t: -------------------------------------------------------------------------------- 1 | $ cat >test.ml < [%%ocaml.error "test with several words"] 3 | > EOF 4 | 5 | $ $MERLIN single errors -filename test.ml let minimal : type a. 'a t 3 | > EOF 4 | { 5 | "class": "return", 6 | "value": [ 7 | { 8 | "start": { 9 | "line": 1, 10 | "col": 22 11 | }, 12 | "end": { 13 | "line": 1, 14 | "col": 24 15 | }, 16 | "type": "parser", 17 | "sub": [], 18 | "valid": true, 19 | "message": "In this scoped type, variable 'a is reserved for the local type a." 20 | } 21 | ], 22 | "notifications": [] 23 | } 24 | 25 | Merlin would fail to catch this new exception: 26 | "In this scoped type, variable 'a is reserved for the local type a.", 27 | -------------------------------------------------------------------------------- /tests/test-dirs/errors/issue1794.t: -------------------------------------------------------------------------------- 1 | $ $MERLIN single errors -filename main.ml -unboxed-types 2 | { 3 | "class": "return", 4 | "value": [], 5 | "notifications": [] 6 | } 7 | 8 | $ $MERLIN single errors -filename main.ml -no-unboxed-types 9 | { 10 | "class": "return", 11 | "value": [], 12 | "notifications": [] 13 | } 14 | -------------------------------------------------------------------------------- /tests/test-dirs/errors/no-cmi.t: -------------------------------------------------------------------------------- 1 | $ mkdir liba 2 | $ cat >liba/liba.ml < module Libb = Libb 4 | > EOF 5 | 6 | $ mkdir libb 7 | $ cat >libb/libb.ml < let x = 42 9 | > EOF 10 | 11 | $ cat >liba/.merlin < B . 13 | > B ../libb 14 | > EOF 15 | 16 | $ (cd libb && $OCAMLC -c -bin-annot libb.ml) 17 | $ (cd liba && $OCAMLC -c -bin-annot liba.ml -I ../libb) 18 | 19 | 20 | $ ls libb 21 | libb.cmi 22 | libb.cmo 23 | libb.cmt 24 | libb.ml 25 | 26 | There should be no errors 27 | $ cd liba && $MERLIN single errors -filename liba.ml jq '.value' 29 | [] 30 | -------------------------------------------------------------------------------- /tests/test-dirs/errors/reg503.t: -------------------------------------------------------------------------------- 1 | $ cat >test.ml <<'EOF' 2 | > class test _a = 3 | > object 4 | > method b x = x 5 | > end 6 | > EOF 7 | 8 | FIXME: Type variable are not shared between the two parts of the error message: 9 | $ $MERLIN single errors -filename test.ml < test.ml 10 | { 11 | "class": "return", 12 | "value": [ 13 | { 14 | "start": { 15 | "line": 1, 16 | "col": 0 17 | }, 18 | "end": { 19 | "line": 4, 20 | "col": 3 21 | }, 22 | "type": "typer", 23 | "sub": [], 24 | "valid": true, 25 | "message": "Some type variables are unbound in this type: 26 | class test : 'a -> object method b : 'b -> 'b end 27 | The method b has type 'b -> 'b where 'b is unbound" 28 | } 29 | ], 30 | "notifications": [] 31 | } 32 | -------------------------------------------------------------------------------- /tests/test-dirs/errors/typing-after-parsing.t/test.ml: -------------------------------------------------------------------------------- 1 | (* First a typing error *) 2 | 3 | let () = 3 4 | 5 | (* Then a parsing error *) 6 | 7 | let () = | 3 8 | 9 | (* Then a typing error again *) 10 | 11 | let () = 3 12 | -------------------------------------------------------------------------------- /tests/test-dirs/errors/undefined-meth.t: -------------------------------------------------------------------------------- 1 | $ cat >main.ml < let o = object 3 | > method a = 1 4 | > method b = 2 5 | > method cdefg = 2 6 | > end;; 7 | > print_int o#a;; 8 | > print_int o#cdef 9 | > EOF 10 | 11 | $ $MERLIN single errors -filename main.ml tr '\r\n' ' ' | jq '.value[0].message' 13 | "This expression has type < a : int; b : int; cdefg : int > It has no method cdef Hint: Did you mean cdefg?" 14 | -------------------------------------------------------------------------------- /tests/test-dirs/errors/unused-warnings.t: -------------------------------------------------------------------------------- 1 | $ cat >test.ml < open Printf 3 | > 4 | > module type X = sig end 5 | > 6 | > let x = 7 | > let y = 42 in 8 | > () 9 | > 10 | > let _f x = () 11 | > 12 | > type x = { 13 | > foo: int } 14 | > type y = 15 | > | Foo 16 | > 17 | > let () = for i = 0 to 0 do () done 18 | > EOF 19 | 20 | FIXME: It is expected that unused warnings are not shown but the result is 21 | incoherent. 22 | $ $MERLIN single errors -filename test.ml %{os_type} Win32))) 5 | -------------------------------------------------------------------------------- /tests/test-dirs/hidden-deps/hd-directives.t/a/a.ml: -------------------------------------------------------------------------------- 1 | let a = 10 2 | -------------------------------------------------------------------------------- /tests/test-dirs/hidden-deps/hd-directives.t/a/a.mli: -------------------------------------------------------------------------------- 1 | val a : int 2 | -------------------------------------------------------------------------------- /tests/test-dirs/hidden-deps/hd-directives.t/b/b.ml: -------------------------------------------------------------------------------- 1 | include A 2 | let b = 20 3 | -------------------------------------------------------------------------------- /tests/test-dirs/hidden-deps/hd-directives.t/b/b.mli: -------------------------------------------------------------------------------- 1 | val a : int 2 | val b : int 3 | -------------------------------------------------------------------------------- /tests/test-dirs/hidden-deps/hd-directives.t/c/correct.ml: -------------------------------------------------------------------------------- 1 | let c = B.a + B.b 2 | 3 | let () = print_endline (Int.to_string c) 4 | -------------------------------------------------------------------------------- /tests/test-dirs/hidden-deps/hd-directives.t/c/error.ml: -------------------------------------------------------------------------------- 1 | let c = A.a + B.b 2 | 3 | let () = print_endline (Int.to_string c) 4 | -------------------------------------------------------------------------------- /tests/test-dirs/inlay-hint/spec.t: -------------------------------------------------------------------------------- 1 | Start and end should be mandatory 2 | 3 | $ $MERLIN single inlay-hints 4 | { 5 | "class": "failure", 6 | "value": "-start and -end are mandatory", 7 | "notifications": [] 8 | } 9 | 10 | Start should be mandatory 11 | 12 | $ $MERLIN single inlay-hints -end 1 13 | { 14 | "class": "failure", 15 | "value": "-start is mandatory", 16 | "notifications": [] 17 | } 18 | 19 | Stop should be mandatory 20 | 21 | $ $MERLIN single inlay-hints -start 1 22 | { 23 | "class": "failure", 24 | "value": "-end is mandatory", 25 | "notifications": [] 26 | } 27 | -------------------------------------------------------------------------------- /tests/test-dirs/issue1109.t/issue1109.ml: -------------------------------------------------------------------------------- 1 | let rec unit y = y 2 | and f : Unknown_module.t -> _ = 3 | fun y -> y 4 | 5 | let g y = unit y 6 | -------------------------------------------------------------------------------- /tests/test-dirs/issue1109.t/run.t: -------------------------------------------------------------------------------- 1 | $ $MERLIN single type-enclosing -position 5:11 -verbosity 0 \ 2 | > -filename ./issue1109.ml < ./issue1109.ml | jq ".value[0:2]" 3 | [ 4 | { 5 | "start": { 6 | "line": 5, 7 | "col": 10 8 | }, 9 | "end": { 10 | "line": 5, 11 | "col": 14 12 | }, 13 | "type": "'a -> 'a", 14 | "tail": "no" 15 | }, 16 | { 17 | "start": { 18 | "line": 5, 19 | "col": 10 20 | }, 21 | "end": { 22 | "line": 5, 23 | "col": 14 24 | }, 25 | "type": "'a -> 'a", 26 | "tail": "no" 27 | } 28 | ] 29 | -------------------------------------------------------------------------------- /tests/test-dirs/issue1322.t/.merlin: -------------------------------------------------------------------------------- 1 | FLG -short-paths 2 | -------------------------------------------------------------------------------- /tests/test-dirs/issue1322.t/foo.ml: -------------------------------------------------------------------------------- 1 | module type Monad = sig 2 | type 'a t 3 | end 4 | module type Monad_option = 5 | Monad 6 | with type 'a t = 'a option 7 | constraint 'a = int 8 | -------------------------------------------------------------------------------- /tests/test-dirs/issue1322.t/nasty.ml: -------------------------------------------------------------------------------- 1 | module type S = sig 2 | type 'a t = 'a 3 | constraint 'a = < m : r > 4 | and r = (< m : r >) t 5 | end 6 | 7 | module type S = sig type 'a t = 'a constraint 'a = < m : r > and r = < m : r > t end 8 | 9 | module type T = S with type 'a t = 'b constraint 'a = < m : 'b > 10 | -------------------------------------------------------------------------------- /tests/test-dirs/issue1322.t/run.t: -------------------------------------------------------------------------------- 1 | $ $MERLIN single errors -filename foo.ml < foo.ml 2 | { 3 | "class": "return", 4 | "value": [ 5 | { 6 | "start": { 7 | "line": 5, 8 | "col": 2 9 | }, 10 | "end": { 11 | "line": 7, 12 | "col": 23 13 | }, 14 | "type": "typer", 15 | "sub": [], 16 | "valid": true, 17 | "message": "In this with constraint, the new definition of t 18 | does not match its original definition in the constrained signature: 19 | Type declarations do not match: 20 | type 'a t = 'a t constraint 'a = int 21 | is not included in 22 | type 'a t 23 | Their parameters differ 24 | The type int is not equal to the type 'a 25 | File \"foo.ml\", line 2, characters 2-11: Expected declaration 26 | File \"foo.ml\", lines 6-7, characters 9-23: Actual declaration" 27 | } 28 | ], 29 | "notifications": [] 30 | } 31 | 32 | FIXME (appears undeterministic) 33 | $ $MERLIN single errors -filename nasty.ml < nasty.ml 34 | -------------------------------------------------------------------------------- /tests/test-dirs/issue1506.t: -------------------------------------------------------------------------------- 1 | $ cat >prefix.ml < let ( ?? ) x = 2 * x in 3 | > print_int (?? 21) 4 | > EOF 5 | 6 | $ $OCAMLC -o p.exe prefix.ml 7 | $ ./p.exe 8 | 42 9 | 10 | Fixed: Old holes where interfering with operators (??). And Merlin would report 11 | the folloswng error: "- "message": "let-extension (with punning) expected." 12 | $ $MERLIN single errors \ 13 | > -filename prefix.ml jq '.value' 15 | [] 16 | -------------------------------------------------------------------------------- /tests/test-dirs/issue1518.t: -------------------------------------------------------------------------------- 1 | $ cat >dune-project < (lang dune 2.0) 3 | > EOF 4 | 5 | $ cat >main.ml < print_endline "42" 7 | > EOF 8 | 9 | $ cat >dune < (executable 11 | > (name main) 12 | > (flags :standard -safe-string)) 13 | > EOF 14 | 15 | 16 | $ dune exec ./main.exe 17 | 42 18 | 19 | In 5.0 the compiler still accept the deleted flag "-safe-string". 20 | It simply is a no-op. Merlin should ignore it as well. 21 | $ $MERLIN single errors -filename main.ml jq '.value' 23 | [] 24 | -------------------------------------------------------------------------------- /tests/test-dirs/issue1558.t: -------------------------------------------------------------------------------- 1 | $ cat >main.ml < open Stdlib.Effect 3 | > EOF 4 | 5 | The unstable alert should be disabled by default in OCaml 5 6 | $ $MERLIN single errors -filename main.ml tr '\n' ' ' | jq '.value[0].message' 8 | null 9 | 10 | But can be enabled 11 | $ $MERLIN single errors -filename main.ml -alert +unstable tr '\n' ' ' | jq '.value[0].message' 13 | "Alert unstable: module Stdlib.Effect The Effect interface may change in incompatible ways in the future." 14 | -------------------------------------------------------------------------------- /tests/test-dirs/issue1683-ill-formed-letop.t: -------------------------------------------------------------------------------- 1 | $ cat >main.ml < let (let+) x f = f x 3 | > let (and+) x f = f x 4 | > 5 | > let _ = 6 | > let+ x, _ = 42, 43 7 | > and+ y = 36 and+ _ = 37 in 8 | > x + y 9 | > EOF 10 | 11 | Calling `holes` on the code fragment was raising an exception as 12 | described in issue #1683. 13 | $ $MERLIN single holes -filename main.ml -position 5:7 \ 23 | > -filename main.ml dune-project <<'EOF' 2 | > (lang dune 3.0) 3 | > EOF 4 | 5 | $ cat >dune <<'EOF' 6 | > (executable (name foo)) 7 | > (executable (name foobar) (libraries yojson)) 8 | > EOF 9 | 10 | $ touch foo.ml 11 | 12 | $ cat >foobar.ml <<'EOF' 13 | > let eq = Yojson.equal 14 | > let () = Printf.printf "%b" @@ eq `Null `Null 15 | > EOF 16 | 17 | $ $DUNE build 18 | $ $DUNE exec ./foobar.exe 19 | true 20 | 21 | FIXME: there appear to be an issue with configuration here 22 | $ $MERLIN single locate -position 1:10 \ 23 | > -filename foobar.ml main.ml < let f () = List.map (fun _ -> 3 | > ()) 4 | > let f x y z = 5 | > () 6 | > let f = fun x -> fun y -> fun z -> 7 | > () 8 | > EOF 9 | 10 | Jump to `fun` should not raise an exception and jump to 1:20 11 | $ $MERLIN single jump -target fun -position 2:4 \ 12 | > -filename main.ml -filename main.ml -filename main.ml %{os_type} Win32))) 5 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/ambiguity/not-in-env.t: -------------------------------------------------------------------------------- 1 | FIXME! 2 | 3 | We would like this to say "Not in the environment b", because no label 4 | declaration named b exists. 5 | For this to work, we would need to know that the cursor is on a label name, 6 | which we can't right now when looking on the recovered typedtree. We only know 7 | we're in an expression. 8 | If we switch our context analysis to work on the grammar, this might get better. 9 | Until then ... 10 | 11 | $ $MERLIN single locate -look-for ml -position 2:10 -filename test.ml < let b = 10 13 | > let x = { b = 9 } 14 | > EOF 15 | { 16 | "class": "return", 17 | "value": { 18 | "file": "test.ml", 19 | "pos": { 20 | "line": 1, 21 | "col": 4 22 | } 23 | }, 24 | "notifications": [] 25 | } 26 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/ambiguity/rebinding.t/rebinding.ml: -------------------------------------------------------------------------------- 1 | module X = struct 2 | module Y = struct 3 | module Z = struct 4 | let foo () = () 5 | end 6 | end 7 | end 8 | 9 | open X.Y 10 | 11 | let () = Z.foo () 12 | 13 | module X = X.Y 14 | 15 | let () = Z.foo () 16 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/ambiguity/rebinding.t/run.t: -------------------------------------------------------------------------------- 1 | Jumping to Z.foo before the rebinding of X: 2 | 3 | $ $MERLIN single locate -look-for ml -position 11:13 -filename ./rebinding.ml < ./rebinding.ml 4 | { 5 | "class": "return", 6 | "value": { 7 | "file": "$TESTCASE_ROOT/rebinding.ml", 8 | "pos": { 9 | "line": 4, 10 | "col": 10 11 | } 12 | }, 13 | "notifications": [] 14 | } 15 | 16 | Jumping to Z.foo after the rebinding of X: 17 | 18 | $ $MERLIN single locate -look-for ml -position 15:13 -filename ./rebinding.ml < ./rebinding.ml 19 | { 20 | "class": "return", 21 | "value": { 22 | "file": "$TESTCASE_ROOT/rebinding.ml", 23 | "pos": { 24 | "line": 4, 25 | "col": 10 26 | } 27 | }, 28 | "notifications": [] 29 | } 30 | 31 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/context-detection/cd-field.t/field.ml: -------------------------------------------------------------------------------- 1 | type t = { foo : int } 2 | 3 | let f t = t.foo 4 | 5 | let foo () = 3 6 | 7 | let f t = t.foo 8 | 9 | module X = struct 10 | type t = { bar : int; baz : bool } 11 | end 12 | 13 | let bar = 123 14 | let baz = true 15 | let y = { X.bar ; baz } 16 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/context-detection/cd-from_a_pattern.t/from_a_pattern.ml: -------------------------------------------------------------------------------- 1 | module Blah = struct 2 | type t = 3 | | A 4 | | B 5 | end 6 | 7 | let f = function 8 | | Blah.Q -> () 9 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/context-detection/cd-from_a_pattern.t/run.t: -------------------------------------------------------------------------------- 1 | Confirm there is a type error: 2 | 3 | $ $MERLIN single errors -filename ./from_a_pattern.ml < ./from_a_pattern.ml 4 | { 5 | "class": "return", 6 | "value": [ 7 | { 8 | "start": { 9 | "line": 8, 10 | "col": 4 11 | }, 12 | "end": { 13 | "line": 8, 14 | "col": 10 15 | }, 16 | "type": "typer", 17 | "sub": [], 18 | "valid": true, 19 | "message": "Unbound constructor Blah.Q" 20 | } 21 | ], 22 | "notifications": [] 23 | } 24 | 25 | We call locate from the broken pattern: 26 | 27 | $ $MERLIN single locate -look-for ml -position 8:7 -filename ./from_a_pattern.ml < ./from_a_pattern.ml 28 | { 29 | "class": "return", 30 | "value": { 31 | "file": "$TESTCASE_ROOT/from_a_pattern.ml", 32 | "pos": { 33 | "line": 1, 34 | "col": 7 35 | } 36 | }, 37 | "notifications": [] 38 | } 39 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/context-detection/cd-label.t/label.ml: -------------------------------------------------------------------------------- 1 | type t = { foo : int } 2 | 3 | let foo = 5 4 | let x = { foo } 5 | 6 | (* introducing a syntax error, just to see. *) 7 | 8 | let foo = 5 in 9 | let x = { foo } 10 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/context-detection/cd-mod_constr.t/mod_constr.ml: -------------------------------------------------------------------------------- 1 | type t = String 2 | let x = String.concat 3 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/context-detection/cd-mod_constr.t/run.t: -------------------------------------------------------------------------------- 1 | 2 | $ $MERLIN single locate -look-for ml -position 2:13 -filename ./mod_constr.ml < ./mod_constr.ml 3 | { 4 | "class": "return", 5 | "value": { 6 | "file": "lib/ocaml/string.ml", 7 | "pos": { 8 | "line": 1, 9 | "col": 0 10 | } 11 | }, 12 | "notifications": [] 13 | } 14 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/context-detection/cd-test.t/test.ml: -------------------------------------------------------------------------------- 1 | type a = A 2 | 3 | module type a = sig end 4 | 5 | let a = A 6 | 7 | module type A = a 8 | 9 | module A : A = struct end 10 | 11 | exception A 12 | 13 | type r = { a : a } 14 | 15 | let test = 16 | match ({ a }.a : a) with 17 | | A -> () 18 | | exception A -> () 19 | 20 | exception B = A 21 | 22 | let test = (* don't stress the parser so much *) 23 | let a = { a = A } in 24 | a.a 25 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/context-detection/dune: -------------------------------------------------------------------------------- 1 | (cram 2 | (applies_to cd-field cd-from_a_pattern cd-label cd-mod_constr cd-test) 3 | (enabled_if 4 | (<> %{os_type} Win32))) 5 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/distinguish-files.t/bin/dune: -------------------------------------------------------------------------------- 1 | (executable 2 | (name main) 3 | (libraries lib_a lib_b)) 4 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/distinguish-files.t/bin/main.ml: -------------------------------------------------------------------------------- 1 | let _ = Lib_a.Same.foo 2 | let _ = Lib_b.Same.foo 3 | 4 | let _ = Lib_a.Different.foo 5 | let _ = Lib_b.Different.foo 6 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/distinguish-files.t/dune-project: -------------------------------------------------------------------------------- 1 | (lang dune 2.0) 2 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/distinguish-files.t/lib_a/different.ml: -------------------------------------------------------------------------------- 1 | (* AAAAA *) 2 | let foo = 10 3 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/distinguish-files.t/lib_a/dune: -------------------------------------------------------------------------------- 1 | (library 2 | (name lib_a)) 3 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/distinguish-files.t/lib_a/same.ml: -------------------------------------------------------------------------------- 1 | let foo = 10 2 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/distinguish-files.t/lib_b/different.ml: -------------------------------------------------------------------------------- 1 | (* BBBBB *) 2 | let foo = 10 3 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/distinguish-files.t/lib_b/dune: -------------------------------------------------------------------------------- 1 | (library 2 | (name lib_b)) 3 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/distinguish-files.t/lib_b/same.ml: -------------------------------------------------------------------------------- 1 | let foo = 10 2 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/distinguish-files.t/run.t: -------------------------------------------------------------------------------- 1 | Merlin can distinguish between two files with the same name and contents 2 | 3 | $ dune build @check 4 | 5 | Part 1: Test that two files with the same name but different contents can be distinguished 6 | 7 | Get Lib_a.Different.foo 8 | $ $MERLIN single locate -position 4:26 -filename bin/main.ml < bin/main.ml \ 9 | > | jq .value.file -r 10 | $TESTCASE_ROOT/lib_a/different.ml 11 | 12 | Get Lib_b.Different.foo 13 | $ $MERLIN single locate -position 5:26 -filename bin/main.ml < bin/main.ml \ 14 | > | jq .value.file -r 15 | $TESTCASE_ROOT/lib_b/different.ml 16 | 17 | Part 2: Test that two files with the same name and same contents can be distinguished 18 | 19 | Get Lib_a.Same.foo 20 | $ $MERLIN single locate -position 1:22 -filename bin/main.ml < bin/main.ml \ 21 | > | jq .value.file -r 22 | $TESTCASE_ROOT/lib_a/same.ml 23 | 24 | Get Lib_b.Same.foo 25 | $ $MERLIN single locate -position 2:22 -filename bin/main.ml < bin/main.ml \ 26 | > | jq .value.file -r 27 | $TESTCASE_ROOT/lib_b/same.ml 28 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/dune: -------------------------------------------------------------------------------- 1 | (cram 2 | (applies_to looping-substitution mutually-recursive partial-cmt includes 3 | issue802 issue845 issue1848 issue1199 issue1524 sig-substs l-413-features 4 | module-aliases locate-constrs without-implem without-sig module-decl-aliases 5 | in-implicit-trans-dep distinguish-files) 6 | (enabled_if 7 | (<> %{os_type} Win32))) 8 | 9 | (cram 10 | (applies_to issue1424 module-aliases in-generated-file) 11 | (enabled_if 12 | (and 13 | (<> %{architecture} i386) 14 | (<> %{os_type} Win32)))) 15 | 16 | (cram 17 | (applies_to :whole_subtree) 18 | (alias all-locate-tests)) 19 | 20 | (cram 21 | (applies_to in-implicit-trans-dep) 22 | (enabled_if (>= %{read:version/dune.txt} "3.16"))) 23 | 24 | (subdir 25 | version 26 | (rule (action (with-stdout-to dune.txt (run dune --version))))) 27 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/functors/dune: -------------------------------------------------------------------------------- 1 | (cram 2 | (applies_to f-all_local f-from_application f-generative f-included 3 | f-missed_shadowing f-nested_applications f-test-ml-mli) 4 | (enabled_if 5 | (<> %{os_type} Win32))) 6 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/functors/f-all_local.t/all_local.ml: -------------------------------------------------------------------------------- 1 | module type S = sig 2 | type t 3 | end 4 | 5 | module M = struct 6 | type t = T 7 | end 8 | 9 | module Make(Arg : S) : S = struct 10 | include Arg 11 | 12 | type x = t 13 | 14 | let foo : x -> x = 15 | fun x -> x 16 | end 17 | 18 | module Foo = Make(M) 19 | 20 | type t = Foo.t 21 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/functors/f-from_application.t/from_application.ml: -------------------------------------------------------------------------------- 1 | module Make(X : sig type t end) = struct 2 | type t = X.t list 3 | end 4 | 5 | module A = struct 6 | type t = int 7 | end 8 | 9 | type a = A 10 | 11 | module M1 = Make(A) 12 | 13 | module M2 = Make(struct 14 | type indir = a 15 | 16 | let _noise = () 17 | 18 | type t = indir 19 | end) 20 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/functors/f-generative.t/generative.ml: -------------------------------------------------------------------------------- 1 | module type S = sig 2 | 3 | val foo : int -> int 4 | 5 | end 6 | 7 | module Make (Foo : sig type t end) (Bar : sig end) () : S = struct 8 | let foo x = x + 1 9 | end 10 | 11 | module M = Make(struct type t = int end)(struct end)() 12 | 13 | let x = M.foo 14 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/functors/f-generative.t/run.t: -------------------------------------------------------------------------------- 1 | Check that we handle generative functors properly: 2 | 3 | $ $MERLIN single locate -look-for mli -position 13:12 -filename generative.ml < generative.ml 4 | { 5 | "class": "return", 6 | "value": { 7 | "file": "$TESTCASE_ROOT/generative.ml", 8 | "pos": { 9 | "line": 3, 10 | "col": 6 11 | } 12 | }, 13 | "notifications": [] 14 | } 15 | 16 | $ $MERLIN single locate -look-for ml -position 13:12 -filename generative.ml < generative.ml 17 | { 18 | "class": "return", 19 | "value": { 20 | "file": "$TESTCASE_ROOT/generative.ml", 21 | "pos": { 22 | "line": 8, 23 | "col": 6 24 | } 25 | }, 26 | "notifications": [] 27 | } 28 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/functors/f-included.t/included.ml: -------------------------------------------------------------------------------- 1 | module type S = sig 2 | type t 3 | end 4 | 5 | module Set(Elt : S) : sig 6 | type elt = Elt.t 7 | type set = private elt list 8 | 9 | val empty : set 10 | end = struct 11 | type elt = Elt.t 12 | type set = elt list 13 | 14 | let empty = [] 15 | end 16 | 17 | module Str = struct 18 | include String 19 | include Set(String) 20 | end 21 | 22 | let e = Str.empty 23 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/functors/f-included.t/run.t: -------------------------------------------------------------------------------- 1 | 2 | $ $MERLIN single locate -look-for ml -position 22:15 \ 3 | > -filename ./included.ml < ./included.ml 4 | { 5 | "class": "return", 6 | "value": { 7 | "file": "$TESTCASE_ROOT/included.ml", 8 | "pos": { 9 | "line": 14, 10 | "col": 6 11 | } 12 | }, 13 | "notifications": [] 14 | } 15 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/functors/f-missed_shadowing.t/missed_shadowing.ml: -------------------------------------------------------------------------------- 1 | module W = struct end 2 | 3 | module M (W : sig end) : sig end = struct 4 | include W 5 | end 6 | 7 | module type X = sig end 8 | 9 | module N (X : X) : sig end = struct 10 | include X 11 | end 12 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/functors/f-missed_shadowing.t/run.t: -------------------------------------------------------------------------------- 1 | Reproduce bug described (and fixed) in commit e558d203334fd06f7653a6388b46dba895fb3ce9 2 | 3 | $ $MERLIN single locate -look-for ml -position 4:10 \ 4 | > -filename ./missed_shadowing.ml < ./missed_shadowing.ml 5 | { 6 | "class": "return", 7 | "value": { 8 | "file": "$TESTCASE_ROOT/missed_shadowing.ml", 9 | "pos": { 10 | "line": 3, 11 | "col": 10 12 | } 13 | }, 14 | "notifications": [] 15 | } 16 | 17 | $ $MERLIN single locate -look-for ml -position 9:15 \ 18 | > -filename ./missed_shadowing.ml < ./missed_shadowing.ml 19 | { 20 | "class": "return", 21 | "value": { 22 | "file": "$TESTCASE_ROOT/missed_shadowing.ml", 23 | "pos": { 24 | "line": 7, 25 | "col": 12 26 | } 27 | }, 28 | "notifications": [] 29 | } 30 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/functors/f-nested_applications.t/nested_applications.ml: -------------------------------------------------------------------------------- 1 | module type S = sig 2 | type t 3 | end 4 | 5 | module Identity(X : S) : S = X 6 | 7 | module Apply(Id : S -> S) = Id 8 | 9 | module Simple = struct 10 | type t 11 | end 12 | 13 | module M1 = Identity(Identity(Simple)) 14 | 15 | module M2 = Apply(Identity)(Simple) 16 | 17 | type t1 = M1.t 18 | 19 | type t2 = M2.t 20 | 21 | module Alternative_apply(Id : S -> S)(X : S) = struct include Id(X) end 22 | 23 | module M3 = Alternative_apply(Identity)(Simple) 24 | 25 | type t3 = M3.t 26 | 27 | module M4 = Alternative_apply(functor(X : S) -> X)(Simple) 28 | 29 | type t4 = M4.t 30 | 31 | module M5 = Identity((functor(X : S) -> X)(Simple)) 32 | 33 | type t5 = M5.t 34 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/functors/f-test-ml-mli.t: -------------------------------------------------------------------------------- 1 | $ cat >dune-project < (lang dune 2.0) 3 | > EOF 4 | 5 | $ cat >mySet.mli < module Make : functor (Arg : sig type t end) -> sig 7 | > type t 8 | > end 9 | > EOF 10 | 11 | $ cat >mySet.ml < module Make (Arg : sig type t end) = struct 13 | > type t = Arg.t 14 | > end 15 | > EOF 16 | 17 | $ cat >s.ml < module Foo = MySet.Make(struct 19 | > type t 20 | > end) 21 | > type t = Foo.t 22 | > EOF 23 | 24 | $ cat >dune < (executable (name s)) 26 | > EOF 27 | 28 | $ dune build @check 29 | 30 | Should jump to mySet.ml: 31 | $ $MERLIN single locate -look-for ml -position 4:13 \ 32 | > -filename ./s.ml < ./s.ml | jq '.value' 33 | { 34 | "file": "$TESTCASE_ROOT/mySet.ml", 35 | "pos": { 36 | "line": 2, 37 | "col": 7 38 | } 39 | } 40 | 41 | Should jump to mySet.mli: 42 | $ $MERLIN single locate -look-for mli -position 4:13 \ 43 | > -filename ./s.ml < ./s.ml | jq '.value' 44 | { 45 | "file": "$TESTCASE_ROOT/mySet.mli", 46 | "pos": { 47 | "line": 2, 48 | "col": 7 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/ill-typed/local-open.t: -------------------------------------------------------------------------------- 1 | $ cat >open.ml < let x = false 3 | > let f () = 4 | > let open Unknown in 5 | > x 6 | > ;; 7 | > EOF 8 | 9 | $ $MERLIN single locate -position 4:2 \ 10 | > -filename open.ml = 5.2 6 | $ $MERLIN single locate -look-for ml -position 1:15 \ 7 | > -filename bin/main.ml func.ml < module Make () = struct 6 | > let u = () 7 | > end 8 | > 9 | > module T = Make ();; 10 | > 11 | > let () = T.u 12 | > EOF 13 | 14 | $ $MERLIN single locate -look-for ml -position 7:11 -filename ./func.ml < ./func.ml 15 | { 16 | "class": "return", 17 | "value": { 18 | "file": "$TESTCASE_ROOT/func.ml", 19 | "pos": { 20 | "line": 2, 21 | "col": 6 22 | } 23 | }, 24 | "notifications": [] 25 | } 26 | $ $MERLIN single locate -look-for ml -position 7:9 -filename ./func.ml < ./func.ml 27 | { 28 | "class": "return", 29 | "value": { 30 | "file": "$TESTCASE_ROOT/func.ml", 31 | "pos": { 32 | "line": 5, 33 | "col": 7 34 | } 35 | }, 36 | "notifications": [] 37 | } 38 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/issue1398.t/issue1398.ml: -------------------------------------------------------------------------------- 1 | let (let++) x f = f x 2 | let (and++) a b = (a, b) ;; 3 | let ops = (let++), (and++) ;; 4 | let++ x = 3 and++ y = 4 in x + y 5 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/issue1424.t: -------------------------------------------------------------------------------- 1 | $ cat >dune-project < (lang dune 2.8) 3 | > EOF 4 | 5 | $ cat >dune < (executable (name test)) 7 | > EOF 8 | 9 | $ cat >test.ml < let _ = Test2.foo 11 | > EOF 12 | 13 | $ cat >test2.ml < let foo = 42 15 | > EOF 16 | 17 | $ cat >test2.mli < val foo : int 19 | > EOF 20 | 21 | NOTE: we need to build the @check target to have the cmt and not only the cmti 22 | $ dune build @check 23 | 24 | Jump to interface: 25 | $ $MERLIN single locate -look-for mli -position 1:16 \ 26 | > -filename test.ml -filename test.ml main.ml < type t = { 3 | > data : int; 4 | > } 5 | > let f x = 6 | > x.data + 1 7 | > EOF 8 | 9 | 10 | $ $MERLIN single locate -look-for mli -position 5:6 \ 11 | > -filename ./main.ml < ./main.ml | jq '.value' 12 | { 13 | "file": "$TESTCASE_ROOT/main.ml", 14 | "pos": { 15 | "line": 2, 16 | "col": 2 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/issue1667.t: -------------------------------------------------------------------------------- 1 | $ cat >main.ml < module B = struct 3 | > module type T = sig end 4 | > 5 | > module T = struct end 6 | > end 7 | > 8 | > module M : B.T = struct end 9 | > module type T2 = B.T 10 | > module M2 : T2 = struct end 11 | > EOF 12 | 13 | $ $MERLIN single locate -look-for mli -position 7:13 \ 14 | > -filename ./main.ml < ./main.ml | jq '.value.pos' 15 | { 16 | "line": 2, 17 | "col": 14 18 | } 19 | 20 | $ $MERLIN single locate -look-for ml -position 7:13 \ 21 | > -filename ./main.ml < ./main.ml | jq '.value.pos' 22 | { 23 | "line": 2, 24 | "col": 14 25 | } 26 | 27 | 28 | $ $MERLIN single locate -look-for mli -position 9:12 \ 29 | > -filename ./main.ml < ./main.ml | jq '.value.pos' 30 | { 31 | "line": 2, 32 | "col": 14 33 | } 34 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/issue1842.t: -------------------------------------------------------------------------------- 1 | $ cat >dune-project <<'EOF' 2 | > (lang dune 3.0) 3 | > EOF 4 | 5 | $ mkdir real_source 6 | 7 | $ cat >real_source/pparse.ml <<'EOF' 8 | > let x = "Hello" 9 | > EOF 10 | 11 | $ mkdir source 12 | 13 | $ cat >source/main.ml <<'EOF' 14 | > let () = print_endline Pparse.x 15 | > EOF 16 | 17 | $ cat >source/dune <<'EOF' 18 | > (rule (copy# ../real_source/pparse.ml pparse.ml)) 19 | > (executable (name main)) 20 | > EOF 21 | 22 | 23 | $ dune build @check 24 | $ dune exec ./source/main.exe 25 | Hello 26 | 27 | $ $MERLIN single locate -look-for ml -position 1:30 \ 28 | > -filename source/main.ml main.ml < module A = struct let (+.) a b = a +. b end 5 | > let f x = A.(x +. 1.) 6 | > let g x = A.(+.) x 1. 7 | > EOF 8 | 9 | $ $MERLIN single locate -look-for ml -position 2:16 \ 10 | > -filename ./main.ml < ./main.ml | jq '.value.pos' 11 | { 12 | "line": 1, 13 | "col": 22 14 | } 15 | 16 | $ $MERLIN single locate -look-for ml -position 3:14 \ 17 | > -filename ./main.ml < ./main.ml | jq '.value.pos' 18 | { 19 | "line": 1, 20 | "col": 22 21 | } 22 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/local-definitions/dune: -------------------------------------------------------------------------------- 1 | (cram 2 | (applies_to issue798 issue806) 3 | (enabled_if 4 | (<> %{os_type} Win32))) 5 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/local-definitions/issue798.t/issue798.ml: -------------------------------------------------------------------------------- 1 | module List = 2 | struct 3 | include List 4 | let foo l = 5 | match l with 6 | | hd :: tl -> 7 | let _ = hd in 8 | assert false 9 | | [] -> 10 | assert false 11 | end 12 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/local-definitions/issue798.t/run.t: -------------------------------------------------------------------------------- 1 | 2 | $ $MERLIN single locate -look-for ml -position 7:17 -filename ./issue798.ml < ./issue798.ml 3 | { 4 | "class": "return", 5 | "value": { 6 | "file": "$TESTCASE_ROOT/issue798.ml", 7 | "pos": { 8 | "line": 6, 9 | "col": 8 10 | } 11 | }, 12 | "notifications": [] 13 | } 14 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/local-definitions/issue806.t/issue806.ml: -------------------------------------------------------------------------------- 1 | let foo () = () 2 | 3 | let () = 4 | let foo () = () in 5 | foo () 6 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/local-definitions/issue806.t/run.t: -------------------------------------------------------------------------------- 1 | 2 | $ $MERLIN single locate -look-for ml -position 5:3 -filename ./issue806.ml < ./issue806.ml 3 | { 4 | "class": "return", 5 | "value": { 6 | "file": "$TESTCASE_ROOT/issue806.ml", 7 | "pos": { 8 | "line": 4, 9 | "col": 6 10 | } 11 | }, 12 | "notifications": [] 13 | } 14 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/local-locate.t: -------------------------------------------------------------------------------- 1 | $ cat >main.ml < let _ = let x = 42 in x 3 | > EOF 4 | 5 | $ $MERLIN single locate -look-for ml -position 1:22 \ 6 | > -filename main.ml -filename main.ml $MERLIN single locate -look-for ml -position 1:15 -filename ./example.ml 11 | { 12 | "class": "return", 13 | "value": { 14 | "file": "$TESTCASE_ROOT/test.ml", 15 | "pos": { 16 | "line": 5, 17 | "col": 4 18 | } 19 | }, 20 | "notifications": [] 21 | } 22 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/looping-substitution.t/test.ml: -------------------------------------------------------------------------------- 1 | module type S = sig 2 | val the_function : unit -> unit 3 | end 4 | 5 | let the_function () = () 6 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/module-aliases.t/anothermod.ml: -------------------------------------------------------------------------------- 1 | 2 | type a 3 | let f x = 2 * x 4 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/module-aliases.t/anothermod.mli: -------------------------------------------------------------------------------- 1 | 2 | type a 3 | val f : int -> int 4 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/module-aliases.t/dune: -------------------------------------------------------------------------------- 1 | (executable 2 | (name main)) 3 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/module-aliases.t/dune-project: -------------------------------------------------------------------------------- 1 | (lang dune 2.0) 2 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/module-aliases.t/main.ml: -------------------------------------------------------------------------------- 1 | module Arith = Anothermod 2 | 3 | type u = Anothermod.a;; 4 | 5 | Arith.f 42 6 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/mutually-recursive.t/issue973.ml: -------------------------------------------------------------------------------- 1 | let rec foo x = 2 | 1 + bar x 3 | 4 | and bar x = 5 | if x = 0 then 6 | x 7 | else 8 | foo (x - 1) 9 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/mutually-recursive.t/run.t: -------------------------------------------------------------------------------- 1 | Searching foo from bar works: 2 | 3 | $ $MERLIN single locate -look-for ml -position 8:6 -filename ./issue973.ml < ./issue973.ml 4 | { 5 | "class": "return", 6 | "value": { 7 | "file": "$TESTCASE_ROOT/issue973.ml", 8 | "pos": { 9 | "line": 1, 10 | "col": 8 11 | } 12 | }, 13 | "notifications": [] 14 | } 15 | 16 | And so does bar from foo: 17 | 18 | $ $MERLIN single locate -look-for ml -position 2:7 -filename ./issue973.ml < ./issue973.ml 19 | { 20 | "class": "return", 21 | "value": { 22 | "file": "$TESTCASE_ROOT/issue973.ml", 23 | "pos": { 24 | "line": 4, 25 | "col": 4 26 | } 27 | }, 28 | "notifications": [] 29 | } 30 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/non-local/dune: -------------------------------------------------------------------------------- 1 | (cram 2 | (applies_to ignore-kept-locs preference) 3 | (enabled_if 4 | (<> %{os_type} Win32))) 5 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/non-local/ignore-kept-locs.t/a.ml: -------------------------------------------------------------------------------- 1 | let value = 3 2 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/non-local/ignore-kept-locs.t/b.ml: -------------------------------------------------------------------------------- 1 | let _ = A.value 2 | 3 | include A 4 | 5 | let _ = value 6 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/non-local/preference.t/a.ml: -------------------------------------------------------------------------------- 1 | let value = 3 2 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/non-local/preference.t/a.mli: -------------------------------------------------------------------------------- 1 | (* a comment! *) 2 | 3 | val value : int 4 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/non-local/preference.t/b.ml: -------------------------------------------------------------------------------- 1 | let _ = A.value 2 | 3 | module Indir = A 4 | 5 | let _ = Indir.value 6 | 7 | include A 8 | 9 | let _ = value 10 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/non-local/preference.t/b.mli: -------------------------------------------------------------------------------- 1 | (* deliberately empty *) 2 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/predef.t: -------------------------------------------------------------------------------- 1 | $ cat > predef.ml < true 3 | > EOF 4 | 5 | $ $MERLIN single locate -look-for ml -position 1:2 \ 6 | > -filename ./predef.ml < ./predef.ml 7 | { 8 | "class": "return", 9 | "value": "\"true\" is a builtin, and it is therefore impossible to jump to its definition", 10 | "notifications": [] 11 | } 12 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/reconstruct-identifier/dune: -------------------------------------------------------------------------------- 1 | (cram 2 | (applies_to newlines off_by_one) 3 | (enabled_if 4 | (<> %{os_type} Win32))) 5 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/reconstruct-identifier/newlines.t/escaped_newline.ml: -------------------------------------------------------------------------------- 1 | let string = "s" 2 | 3 | let foo = 4 | let _ = {| Look at this: '\ 5 | Foo|} in 6 | let () = ignore string in 7 | "Onoes, Foo_bar_lol baz" 8 | ;; 9 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/reconstruct-identifier/newlines.t/newline_in_quotes.ml: -------------------------------------------------------------------------------- 1 | let string = "s" 2 | 3 | let foo = 4 | let _ = {| Look at this: ' 5 | ' 6 | Foo|} in 7 | let () = ignore string in 8 | "Onoes, Foo_bar_lol baz" 9 | ;; 10 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/reconstruct-identifier/newlines.t/run.t: -------------------------------------------------------------------------------- 1 | We need to be careful about newlines in Lexer_ident: 2 | 3 | $ $MERLIN single locate -look-for ml -position 7:20 \ 4 | > -filename ./newline_in_quotes.ml < ./newline_in_quotes.ml 5 | { 6 | "class": "return", 7 | "value": { 8 | "file": "$TESTCASE_ROOT/newline_in_quotes.ml", 9 | "pos": { 10 | "line": 1, 11 | "col": 4 12 | } 13 | }, 14 | "notifications": [] 15 | } 16 | 17 | $ $MERLIN single locate -look-for ml -position 6:20 \ 18 | > -filename ./escaped_newline.ml < ./escaped_newline.ml 19 | { 20 | "class": "return", 21 | "value": { 22 | "file": "$TESTCASE_ROOT/escaped_newline.ml", 23 | "pos": { 24 | "line": 1, 25 | "col": 4 26 | } 27 | }, 28 | "notifications": [] 29 | } 30 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/reconstruct-identifier/off_by_one.t/off_by_one.ml: -------------------------------------------------------------------------------- 1 | module Wx = struct type t end 2 | 3 | module type Q = sig 4 | val f : x:Wx.t -> unit 5 | end 6 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/reconstruct-identifier/off_by_one.t/run.t: -------------------------------------------------------------------------------- 1 | Regression test for #624 2 | 3 | $ $MERLIN single locate -look-for ml -position 4:13 -filename ./off_by_one.ml < ./off_by_one.ml 4 | { 5 | "class": "return", 6 | "value": { 7 | "file": "$TESTCASE_ROOT/off_by_one.ml", 8 | "pos": { 9 | "line": 1, 10 | "col": 7 11 | } 12 | }, 13 | "notifications": [] 14 | } 15 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/record_pun.t: -------------------------------------------------------------------------------- 1 | ############ 2 | With punning 3 | ############ 4 | 5 | $ cat > func.ml < module M = struct 7 | > type t = { foo : int } 8 | > 9 | > let foo = 42 10 | > end 11 | > 12 | > let foo = 43 13 | > 14 | > let m = { M.foo } 15 | > 16 | > EOF 17 | 18 | With punning we jump to the definition of the value and not the record: 19 | $ $MERLIN single locate -look-for ml -position 9:14 \ 20 | > -filename ./func.ml < ./func.ml | 21 | > jq '.value.pos' 22 | { 23 | "line": 4, 24 | "col": 6 25 | } 26 | 27 | ############### 28 | Without punning 29 | ############### 30 | 31 | $ cat > func.ml < module M = struct 33 | > type t = { foo : int } 34 | > 35 | > let foo = 42 36 | > end 37 | > 38 | > let foo = 43 39 | > 40 | > let m = { M.foo } 41 | > 42 | > EOF 43 | 44 | FIXME should jump to the re-definition of `foo` line 7 45 | $ $MERLIN single locate -look-for ml -position 9:14 \ 46 | > -filename ./func.ml < ./func.ml | 47 | > jq '.value.pos' 48 | { 49 | "line": 4, 50 | "col": 6 51 | } 52 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/sig-substs.t/basic.ml: -------------------------------------------------------------------------------- 1 | module type S = sig 2 | module type T = sig 3 | type t 4 | end 5 | 6 | type lol 7 | 8 | module M : T with type t = lol 9 | 10 | val x : M.t 11 | end 12 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/sig-substs.t/run.t: -------------------------------------------------------------------------------- 1 | FIXME: such substitutions are not handled properly yet. 2 | On a similar note we currently have no way to decide between a sig and a struct 3 | when both are present in the buffer (the struct will always be preferred). 4 | 5 | $ $MERLIN single locate -look-for ml -position 10:11 -filename ./basic.ml < ./basic.ml 6 | { 7 | "class": "return", 8 | "value": { 9 | "file": "$TESTCASE_ROOT/basic.ml", 10 | "pos": { 11 | "line": 8, 12 | "col": 9 13 | } 14 | }, 15 | "notifications": [] 16 | } 17 | 18 | TODO SHAPES: it could be more precise by answering 8:21 19 | $ $MERLIN single locate -look-for ml -position 10:13 -filename ./basic.ml < ./basic.ml 20 | { 21 | "class": "return", 22 | "value": { 23 | "file": "$TESTCASE_ROOT/basic.ml", 24 | "pos": { 25 | "line": 8, 26 | "col": 25 27 | } 28 | }, 29 | "notifications": [] 30 | } 31 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/with-holes.t/run.t: -------------------------------------------------------------------------------- 1 | $ cat >bar.ml < module M = struct 3 | > include _ 4 | > let x = 3 5 | > end 6 | > let _ = M.x 7 | > let _ = M.foo 8 | > EOF 9 | 10 | $ $MERLIN single locate -look-for ml -position 5:11 -filename bar.ml jq '.value.pos' 12 | { 13 | "line": 3, 14 | "col": 5 15 | } 16 | 17 | $ $MERLIN single locate -look-for ml -position 6:11 -filename bar.ml jq '.value' 19 | "Not in environment 'M.foo'" 20 | 21 | $ $MERLIN single locate -look-for ml -position 2:10 -filename bar.ml external foo : unit list = "foo" 7 | > EOF 8 | { 9 | "class": "return", 10 | "value": [], 11 | "notifications": [] 12 | } 13 | -------------------------------------------------------------------------------- /tests/test-dirs/misc/load_path.t: -------------------------------------------------------------------------------- 1 | $ echo "let x = List.map" >test.ml 2 | 3 | Shadow the list module from the stdlib: 4 | 5 | $ echo "let map = 3" >list.ml 6 | $ $OCAMLC -c list.ml 7 | 8 | Here is what the compiler sees: 9 | 10 | $ $OCAMLC -c -i test.ml 11 | val x : int 12 | 13 | Here is what merlin sees: 14 | 15 | $ $MERLIN single type-enclosing -position 1:14 -filename test.ml < test.ml 16 | { 17 | "class": "return", 18 | "value": [ 19 | { 20 | "start": { 21 | "line": 1, 22 | "col": 8 23 | }, 24 | "end": { 25 | "line": 1, 26 | "col": 16 27 | }, 28 | "type": "int", 29 | "tail": "no" 30 | }, 31 | { 32 | "start": { 33 | "line": 1, 34 | "col": 8 35 | }, 36 | "end": { 37 | "line": 1, 38 | "col": 16 39 | }, 40 | "type": "int", 41 | "tail": "no" 42 | } 43 | ], 44 | "notifications": [] 45 | } 46 | -------------------------------------------------------------------------------- /tests/test-dirs/motion/phrase.t: -------------------------------------------------------------------------------- 1 | $ $MERLIN single phrase -target next -position 1:0 -filename test.ml < let x = 5 3 | > let y = 2 4 | > EOF 5 | { 6 | "class": "return", 7 | "value": { 8 | "pos": { 9 | "line": 2, 10 | "col": 0 11 | } 12 | }, 13 | "notifications": [] 14 | } 15 | 16 | FIXME: ?? 17 | 18 | $ $MERLIN single phrase -target prev -position 2:0 -filename test.ml < let x = 5 20 | > let y = 2 21 | > EOF 22 | { 23 | "class": "return", 24 | "value": { 25 | "pos": { 26 | "line": 1, 27 | "col": 0 28 | } 29 | }, 30 | "notifications": [] 31 | } 32 | -------------------------------------------------------------------------------- /tests/test-dirs/no-escape.t/foo.cmi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ocaml/merlin/754ec9eacf5b4fd6525a16609a2406175d59013e/tests/test-dirs/no-escape.t/foo.cmi -------------------------------------------------------------------------------- /tests/test-dirs/no-escape.t/test_open.ml: -------------------------------------------------------------------------------- 1 | (* TODO or FIXME: If file is empty, Merlin just drops the errors 2 | (errors are attached to typed top-level definitions, 3 | if there are no definitions, errors cannot be attached!) 4 | 5 | So here is a dummy definition. 6 | *) 7 | 8 | 9 | let () = print_string "Hello world" 10 | -------------------------------------------------------------------------------- /tests/test-dirs/no-escape.t/test_use.ml: -------------------------------------------------------------------------------- 1 | open Foo 2 | -------------------------------------------------------------------------------- /tests/test-dirs/occurrences/basic.t/basic.ml: -------------------------------------------------------------------------------- 1 | let simple some = 2 | some + some 3 | 4 | let withTypeAnnot (some : int) = 5 | some + some 6 | 7 | type boxed_int = {value : int} 8 | 9 | let withRecordPattern {value;} = 10 | value + value 11 | 12 | let withRecordLiteral num = 13 | {value = num;} 14 | 15 | let withRecordLiteralPunned value = 16 | {value;} 17 | 18 | let withAlias (value as num) = 19 | num + num 20 | -------------------------------------------------------------------------------- /tests/test-dirs/occurrences/dune: -------------------------------------------------------------------------------- 1 | (cram 2 | (applies_to issue1404 issue827) 3 | (enabled_if 4 | (<> %{os_type} Win32))) 5 | 6 | (cram 7 | (applies_to occ-with-ppx) 8 | (enabled_if false)) 9 | -------------------------------------------------------------------------------- /tests/test-dirs/occurrences/issue1398.t/issue1398.ml: -------------------------------------------------------------------------------- 1 | let (let++) x f = f x 2 | let (and++) a b = (a, b) ;; 3 | let ops = (let++), (and++) ;; 4 | let++ x = 3 and++ y = 4 in x + y 5 | -------------------------------------------------------------------------------- /tests/test-dirs/occurrences/issue1410.t: -------------------------------------------------------------------------------- 1 | $ $MERLIN single occurrences -identifier-at 3:3 -filename opt.ml < jq '.value' 3 | > (* test case *) 4 | > let f ?(x=1) () = 2 ;; 5 | > None 6 | > EOF 7 | [ 8 | { 9 | "start": { 10 | "line": 3, 11 | "col": 0 12 | }, 13 | "end": { 14 | "line": 3, 15 | "col": 4 16 | }, 17 | "stale": false 18 | } 19 | ] 20 | 21 | $ $MERLIN single occurrences -identifier-at 3:3 -filename opt.ml < jq '.value' 23 | > (* test case *) 24 | > let f () = 2 ;; 25 | > None 26 | > EOF 27 | [ 28 | { 29 | "start": { 30 | "line": 3, 31 | "col": 0 32 | }, 33 | "end": { 34 | "line": 3, 35 | "col": 4 36 | }, 37 | "stale": false 38 | } 39 | ] 40 | -------------------------------------------------------------------------------- /tests/test-dirs/occurrences/issue827.t/issue827.ml: -------------------------------------------------------------------------------- 1 | module M = struct 2 | type t = AC | BC 3 | end 4 | let _ = M.AC 5 | let _ = let open M in BC 6 | -------------------------------------------------------------------------------- /tests/test-dirs/occurrences/no-def-mli-only.t: -------------------------------------------------------------------------------- 1 | $ cat >noml.mli <<'EOF' 2 | > type t = unit 3 | > EOF 4 | 5 | $ cat >noml.ml <<'EOF' 6 | > type t = unit 7 | > EOF 8 | 9 | $ cat >main.ml <<'EOF' 10 | > let x : Noml.t = () 11 | > let y : Noml.t = () 12 | > EOF 13 | 14 | $ $OCAMLC -c -bin-annot noml.mli noml.ml main.ml 15 | 16 | We remove the source file to mimick cases were generated source files are not 17 | accessible to Merlin. 18 | $ rm noml.ml 19 | 20 | We still expect occurrences of definitions in hidden source files to work 21 | $ $MERLIN single occurrences -identifier-at 2:13 -filename main.ml pat.ml < let f x = 6 | > match x with 7 | > | Some (yyy) -> yyy 8 | > | None -> assert false 9 | > EOF 10 | $ $MERLIN single occurrences -identifier-at 3:10 -filename ./pat.ml < ./pat.ml 11 | { 12 | "class": "return", 13 | "value": [ 14 | { 15 | "start": { 16 | "line": 3, 17 | "col": 10 18 | }, 19 | "end": { 20 | "line": 3, 21 | "col": 13 22 | }, 23 | "stale": false 24 | }, 25 | { 26 | "start": { 27 | "line": 3, 28 | "col": 18 29 | }, 30 | "end": { 31 | "line": 3, 32 | "col": 21 33 | }, 34 | "stale": false 35 | } 36 | ], 37 | "notifications": [] 38 | } 39 | -------------------------------------------------------------------------------- /tests/test-dirs/occurrences/project-wide/dune: -------------------------------------------------------------------------------- 1 | (cram 2 | (applies_to :whole_subtree) 3 | (deps 4 | %{bin:ocaml-index})) 5 | 6 | (cram 7 | (applies_to pwo-ml-gen) 8 | (enabled_if (>= %{read:version/dune.txt} "3.16"))) 9 | 10 | (cram 11 | (applies_to :whole_subtree) 12 | (enabled_if 13 | (<> %{os_type} Win32))) 14 | 15 | (subdir 16 | version 17 | (rule (action (with-stdout-to dune.txt (run dune --version))))) 18 | 19 | -------------------------------------------------------------------------------- /tests/test-dirs/occurrences/project-wide/for-renaming/r-with-functors.t/dune: -------------------------------------------------------------------------------- 1 | (executable 2 | (name main)) 3 | -------------------------------------------------------------------------------- /tests/test-dirs/occurrences/project-wide/for-renaming/r-with-functors.t/dune-project: -------------------------------------------------------------------------------- 1 | (lang dune 3.17) 2 | -------------------------------------------------------------------------------- /tests/test-dirs/occurrences/project-wide/for-renaming/r-with-functors.t/func.ml: -------------------------------------------------------------------------------- 1 | module type P = sig val txt : string end 2 | 3 | module Make (Params : sig val txt : string end) = struct 4 | include Params 5 | end 6 | -------------------------------------------------------------------------------- /tests/test-dirs/occurrences/project-wide/for-renaming/r-with-functors.t/func.mli: -------------------------------------------------------------------------------- 1 | module type P = sig val txt : string end 2 | 3 | module Make (_ : P) : sig 4 | include P 5 | end 6 | -------------------------------------------------------------------------------- /tests/test-dirs/occurrences/project-wide/for-renaming/r-with-functors.t/main.ml: -------------------------------------------------------------------------------- 1 | module P = struct let txt = "Hello world!" end;; 2 | module M = Func.Make(P);; 3 | 4 | print_endline M.txt 5 | -------------------------------------------------------------------------------- /tests/test-dirs/occurrences/project-wide/for-renaming/r-with-functors.t/run.t: -------------------------------------------------------------------------------- 1 | 2 | $ $DUNE build @ocaml-index 3 | 4 | $ $DUNE exec ./main.exe 5 | Hello world! 6 | 7 | We expect 2 occurrences in func.ml, 1 in func.mli and 2 in main.ml 8 | $ $MERLIN single occurrences -scope renaming -identifier-at 4:18 \ 9 | > -filename main.ml lib.ml <<'EOF' 2 | > (* blah *) 3 | > let foo = "bar" 4 | > EOF 5 | 6 | $ cat >main.ml <<'EOF' 7 | > let () = print_string Lib.foo 8 | > EOF 9 | 10 | $ $OCAMLC -bin-annot -bin-annot-occurrences -c lib.ml main.ml 11 | 12 | $ ocaml-index aggregate main.cmt lib.cmt 13 | 14 | Foo was defined on line 2 when the index was built, but is now defined on line 1 15 | $ cat >lib.ml <<'EOF' 16 | > let foo = "bar" 17 | > EOF 18 | 19 | $ $MERLIN single occurrences -scope project -identifier-at 1:28 \ 20 | > -index-file project.ocaml-index \ 21 | > -filename main.ml < main.ml | jq .value 22 | [ 23 | { 24 | "file": "$TESTCASE_ROOT/main.ml", 25 | "start": { 26 | "line": 1, 27 | "col": 26 28 | }, 29 | "end": { 30 | "line": 1, 31 | "col": 29 32 | }, 33 | "stale": false 34 | }, 35 | { 36 | "file": "$TESTCASE_ROOT/lib.ml", 37 | "start": { 38 | "line": 2, 39 | "col": 4 40 | }, 41 | "end": { 42 | "line": 2, 43 | "col": 7 44 | }, 45 | "stale": true 46 | } 47 | ] 48 | -------------------------------------------------------------------------------- /tests/test-dirs/outline.t/foo.mli: -------------------------------------------------------------------------------- 1 | module Bar : sig 2 | type t = int 3 | 4 | module type S1 = sig 5 | type t 6 | val foo : t -> int 7 | end 8 | end 9 | 10 | class type class_type_a = object 11 | method a : int -> int 12 | end 13 | 14 | class class_b : object 15 | method b : string -> string 16 | end 17 | 18 | exception Ex of char 19 | 20 | type ('a, 'b) eithery = Lefty of 'a | Righty of 'b 21 | 22 | type 'a point = { x : 'a; y : 'a; z : 'a } 23 | 24 | class a : object end 25 | 26 | and b : object end 27 | 28 | and c : object end 29 | 30 | class type ta = object end 31 | 32 | and tb = object end 33 | 34 | class b : object 35 | val foo : int 36 | method bar : unit -> unit 37 | end 38 | 39 | and c : object end 40 | 41 | class a : object 42 | val b : < inside_a_b : unit -> unit > 43 | end 44 | 45 | and b : object 46 | val foo : int 47 | method bar : unit 48 | end 49 | 50 | class type ta = object 51 | method baz : int -> int -> string 52 | end 53 | 54 | and tb = object end 55 | 56 | val final_let : < foo : int > 57 | -------------------------------------------------------------------------------- /tests/test-dirs/outline.t/path.ml: -------------------------------------------------------------------------------- 1 | module A = struct 2 | type a = int 3 | end 4 | open A 5 | let x = (5 : a) 6 | -------------------------------------------------------------------------------- /tests/test-dirs/outline.t/path.mli: -------------------------------------------------------------------------------- 1 | module A : sig 2 | type a = int 3 | end 4 | 5 | val x : A.a 6 | -------------------------------------------------------------------------------- /tests/test-dirs/pp/dune: -------------------------------------------------------------------------------- 1 | (cram 2 | (applies_to dot-pp-dot-ml-dune dot-pp-dot-ml simple-pp) 3 | (enabled_if 4 | (<> %{os_type} Win32))) 5 | -------------------------------------------------------------------------------- /tests/test-dirs/refactor-open/functor-app.t/test.ml: -------------------------------------------------------------------------------- 1 | module Wrapper = struct 2 | module type S = sig 3 | type t 4 | val x : t 5 | end 6 | 7 | module Make (X : S) = struct 8 | include X 9 | 10 | let () = ignore x 11 | end 12 | 13 | module C = struct 14 | type t = char 15 | let x = 'a' 16 | end 17 | end 18 | 19 | module I = struct 20 | type t = int 21 | let x = 42 22 | end 23 | 24 | module Hammer = Wrapper 25 | 26 | open Wrapper 27 | 28 | module MC = Hammer (* just because *).Make (Wrapper.C) 29 | module MD = Wrapper.Make (Wrapper.C) 30 | 31 | module MI = Wrapper.Make (I) 32 | 33 | module MC2 = Make (C) 34 | module MI2 = Make (I) 35 | 36 | module MC3 = Make (Wrapper.C) 37 | module MC4 = Wrapper.Make (C) 38 | 39 | type t1 = Wrapper.Make(Wrapper.C).t 40 | type t2 = Make(Wrapper.C).t 41 | type t3 = Wrapper.Make(C).t 42 | type t4 = Make(C).t 43 | -------------------------------------------------------------------------------- /tests/test-dirs/refactor-open/qualify_short_paths.t: -------------------------------------------------------------------------------- 1 | refactor open qualify should use short paths 2 | 3 | $ $MERLIN single refactor-open -action qualify -position 7:6 < module Dune__exe = struct 5 | > module M = struct 6 | > let u = () 7 | > end 8 | > end 9 | > open Dune__exe 10 | > open M 11 | > let u = u 12 | > EOF 13 | { 14 | "class": "return", 15 | "value": [ 16 | { 17 | "start": { 18 | "line": 8, 19 | "col": 8 20 | }, 21 | "end": { 22 | "line": 8, 23 | "col": 9 24 | }, 25 | "content": "M.u" 26 | } 27 | ], 28 | "notifications": [] 29 | } 30 | -------------------------------------------------------------------------------- /tests/test-dirs/search/dune: -------------------------------------------------------------------------------- 1 | (cram 2 | (applies_to :whole_subtree) 3 | (enabled_if 4 | (<> %{os_type} Win32))) 5 | -------------------------------------------------------------------------------- /tests/test-dirs/search/search-by-type.t/context.ml: -------------------------------------------------------------------------------- 1 | let () = () 2 | -------------------------------------------------------------------------------- /tests/test-dirs/server-tests/cache-time.t: -------------------------------------------------------------------------------- 1 | $ $MERLIN server stop-server 2 | 3 | $ cat >dune-project < (lang dune 2.0) 5 | > EOF 6 | 7 | $ cat >dune < 9 | > (executable 10 | > (name main) 11 | > (modules main) 12 | > EOF 13 | 14 | $ cat > main.ml < let () = print_int 0 16 | > EOF 17 | 18 | Let's populate file cache 19 | $ $MERLIN server errors -log-file merlin_logs -cache-lifespan 45 \ 20 | > -filename main.ml 1> /dev/null -filename main.ml 1> /dev/null | tail -1 | sed 's/\ ".*\"//' 27 | keeping 28 | 29 | When cache time is set to 0, file cache gets flushed 30 | $ $MERLIN server errors -log-file merlin_logs -cache-lifespan 0 \ 31 | > -filename main.ml 1> /dev/null | tail -1 | sed 's/\ ".*\"//' 34 | removing 35 | 36 | Stop server 37 | $ $MERLIN server stop-server 38 | -------------------------------------------------------------------------------- /tests/test-dirs/server-tests/chdir_to_root.t: -------------------------------------------------------------------------------- 1 | In case server is running, stop it. 2 | 3 | $ $MERLIN server stop-server 4 | 5 | Check that the working directory of the server process is correctly restored. 6 | 7 | $ touch test.ml 8 | $ export MERLIN_LOG=$(pwd)/log 9 | 10 | $ $MERLIN server errors -filename test.ml < test.ml 1>/dev/null 11 | $ cat log | grep 'old wd' 12 | changed directory to "$TESTCASE_ROOT" (old wd: "/") 13 | $ rm log 14 | 15 | $ $MERLIN server errors -filename test.ml < test.ml 1>/dev/null 16 | $ cat log | grep 'old wd' 17 | changed directory to "$TESTCASE_ROOT" (old wd: "/") 18 | 19 | $ $MERLIN server stop-server 20 | -------------------------------------------------------------------------------- /tests/test-dirs/server-tests/dune: -------------------------------------------------------------------------------- 1 | 2 | (cram 3 | (applies_to :whole_subtree) 4 | (alias all-server-tests) 5 | (locks merlin_server)) 6 | 7 | (cram 8 | (applies_to chdir_to_root incremental-index) 9 | (enabled_if 10 | (<> %{os_type} Win32))) 11 | 12 | (cram 13 | (applies_to pwo-uid-stability ) 14 | (enabled_if 15 | (and 16 | %{bin-available:ocaml-index} 17 | (<> %{os_type} Win32)))) 18 | -------------------------------------------------------------------------------- /tests/test-dirs/server-tests/stable-uids.t: -------------------------------------------------------------------------------- 1 | $ cat >main.ml <<'EOF' 2 | > let x' = 1 3 | > let x = 41 4 | > let f x = x 5 | > let y = f x 6 | > EOF 7 | 8 | $ $MERLIN server occurrences -scope local -identifier-at 3:10 \ 9 | > -log-file log_1 -log-section index \ 10 | > -filename main.ml /dev/null 11 | 12 | $ cat >main.ml <<'EOF' 13 | > let x' = 1 14 | > let x = 42 15 | > let f x = x 16 | > let y = f x 17 | > EOF 18 | 19 | $ $MERLIN server occurrences -scope local -identifier-at 3:10 \ 20 | > -log-file log_2 -log-section index \ 21 | > -filename main.ml /dev/null 22 | 23 | The uids should be the same on both queries: 24 | $ cat log_1 | grep Found | cat >log_1g 25 | $ cat log_2 | grep Found | cat >log_2g 26 | $ diff log_1g log_2g 27 | 28 | $ $MERLIN server stop-server 29 | -------------------------------------------------------------------------------- /tests/test-dirs/server-tests/typer-cache/dune: -------------------------------------------------------------------------------- 1 | (cram 2 | (applies_to stamps) 3 | (enabled_if 4 | (and 5 | (<> %{ocaml_version} 4.12.0+multicore) 6 | (<> %{ocaml_version} 4.12.0+domains)))) 7 | -------------------------------------------------------------------------------- /tests/test-dirs/server-tests/typer-cache/load_path.t/sub/dep.ml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ocaml/merlin/754ec9eacf5b4fd6525a16609a2406175d59013e/tests/test-dirs/server-tests/typer-cache/load_path.t/sub/dep.ml -------------------------------------------------------------------------------- /tests/test-dirs/server-tests/typer-cache/load_path.t/test.ml: -------------------------------------------------------------------------------- 1 | open Dep 2 | -------------------------------------------------------------------------------- /tests/test-dirs/server-tests/typer-cache/sub.t/test.ml: -------------------------------------------------------------------------------- 1 | open Dep 2 | -------------------------------------------------------------------------------- /tests/test-dirs/short-paths/double-trouble.t: -------------------------------------------------------------------------------- 1 | Found in issue #1913 2 | 3 | $ cat >test.ml < type _ plus = | Zero : 'm plus | Suc : 'm plus -> 'm plus 5 | > type _ has_plus = Plus : 'm plus -> unit has_plus;; 6 | > let (Plus (type mn3) (ed : mn3 plus) ) = Plus (Suc Zero) in ed + 2 7 | > EOF 8 | 9 | $ $MERLIN single errors -short-paths -filename test.ml < test.ml 10 | { 11 | "class": "return", 12 | "value": [ 13 | { 14 | "start": { 15 | "line": 3, 16 | "col": 60 17 | }, 18 | "end": { 19 | "line": 3, 20 | "col": 62 21 | }, 22 | "type": "typer", 23 | "sub": [], 24 | "valid": true, 25 | "message": "The value ed has type mn3 plus but an expression was expected of type int" 26 | } 27 | ], 28 | "notifications": [] 29 | } 30 | -------------------------------------------------------------------------------- /tests/test-dirs/short-paths/short-paths.t/dep.mli: -------------------------------------------------------------------------------- 1 | 2 | module M : sig type t end 3 | 4 | type t = M.t 5 | -------------------------------------------------------------------------------- /tests/test-dirs/sp-normalization.t: -------------------------------------------------------------------------------- 1 | $ cat >test.ml <<'EOF' 2 | > module Id = struct 3 | > type 'a t = 'a 4 | > end 5 | > 6 | > module Unit = struct 7 | > type t = unit 8 | > end 9 | > 10 | > type 'a t = 11 | > | Id of 'a t Id.t 12 | > | Unit of Unit.t 13 | > EOF 14 | 15 | This query should not hang indefinitely 16 | $ $MERLIN single type-enclosing -position 11:17 -short-paths \ 17 | > -filename test.ml < test.ml | 18 | > jq '.value' 19 | [ 20 | { 21 | "start": { 22 | "line": 11, 23 | "col": 12 24 | }, 25 | "end": { 26 | "line": 11, 27 | "col": 18 28 | }, 29 | "type": "unit", 30 | "tail": "no" 31 | }, 32 | { 33 | "start": { 34 | "line": 11, 35 | "col": 12 36 | }, 37 | "end": { 38 | "line": 11, 39 | "col": 18 40 | }, 41 | "type": "unit", 42 | "tail": "no" 43 | }, 44 | { 45 | "start": { 46 | "line": 9, 47 | "col": 0 48 | }, 49 | "end": { 50 | "line": 11, 51 | "col": 18 52 | }, 53 | "type": "type 'a t = Id of 'a t | Unit of unit", 54 | "tail": "no" 55 | } 56 | ] 57 | -------------------------------------------------------------------------------- /tests/test-dirs/string-loc.t: -------------------------------------------------------------------------------- 1 | Ensure the Pexp_constant and Pconst_string nodes have different locations. 2 | 3 | $ echo ' "test"' | $MERLIN single dump -what parsetree -filename test.ml 4 | { 5 | "class": "return", 6 | "value": "[ 7 | structure_item (test.ml[1,0+4]..[1,0+10]) 8 | Pstr_eval 9 | expression (test.ml[1,0+4]..[1,0+10]) 10 | Pexp_constant 11 | constant (test.ml[1,0+4]..[1,0+10]) 12 | PConst_string(\"test\",(test.ml[1,0+5]..[1,0+9]),None) 13 | ] 14 | 15 | 16 | ", 17 | "notifications": [] 18 | } 19 | -------------------------------------------------------------------------------- /tests/test-dirs/type-enclosing/503-effects.t: -------------------------------------------------------------------------------- 1 | $ cat >main.ml <<'EOF' 2 | > type _ eff += E : unit eff 3 | > 4 | > let () = 5 | > Printf.printf "%d\n%!" @@ 6 | > match 10 with 7 | > | x -> x 8 | > | effect E, k -> 11 9 | > EOF 10 | 11 | $ $MERLIN single errors -filename main.ml -filename main.ml -filename main.ml () 9 | 10 | module M = struct 11 | type t = A 12 | type u = A | B 13 | end 14 | 15 | let f () = (M.A : M.t) 16 | 17 | let _ = M.A 18 | 19 | module N = struct 20 | type t = A of int 21 | let x = 3 22 | end 23 | 24 | let _ = Some (N.A 3) 25 | 26 | let _ = N.x 27 | -------------------------------------------------------------------------------- /tests/test-dirs/type-enclosing/github1003.t/issue1003.ml: -------------------------------------------------------------------------------- 1 | module List = struct 2 | let foo = 3 3 | end 4 | 5 | let _ = List.foo 6 | -------------------------------------------------------------------------------- /tests/test-dirs/type-enclosing/issue1116.t/issue1116.ml: -------------------------------------------------------------------------------- 1 | let some_int = 5 2 | let x = "some_int" 3 | -------------------------------------------------------------------------------- /tests/test-dirs/type-enclosing/issue1116.t/run.t: -------------------------------------------------------------------------------- 1 | $ $MERLIN single type-enclosing -position 2:13 -verbosity 0 \ 2 | > -filename ./issue1116.ml < ./issue1116.ml | jq ".value[0:2]" 3 | [ 4 | { 5 | "start": { 6 | "line": 2, 7 | "col": 8 8 | }, 9 | "end": { 10 | "line": 2, 11 | "col": 18 12 | }, 13 | "type": "string", 14 | "tail": "no" 15 | } 16 | ] 17 | 18 | $ $MERLIN single type-enclosing -position 1:16 -verbosity 0 \ 19 | > -filename ./issue1116.ml < ./issue1116.ml | jq ".value[0:2]" 20 | [ 21 | { 22 | "start": { 23 | "line": 1, 24 | "col": 15 25 | }, 26 | "end": { 27 | "line": 1, 28 | "col": 16 29 | }, 30 | "type": "int", 31 | "tail": "no" 32 | } 33 | ] 34 | -------------------------------------------------------------------------------- /tests/test-dirs/type-enclosing/issue1226.t: -------------------------------------------------------------------------------- 1 | Fixed. 2 | 3 | $ $MERLIN single type-enclosing -position 5:9 -filename test.ml < module Foo = struct 5 | > let bar = 42 6 | > end 7 | > type t = Foo of int 8 | > let a = Foo 3 9 | > EOF 10 | { 11 | "class": "return", 12 | "value": [ 13 | { 14 | "start": { 15 | "line": 5, 16 | "col": 8 17 | }, 18 | "end": { 19 | "line": 5, 20 | "col": 11 21 | }, 22 | "type": "int -> t", 23 | "tail": "no" 24 | }, 25 | { 26 | "start": { 27 | "line": 5, 28 | "col": 8 29 | }, 30 | "end": { 31 | "line": 5, 32 | "col": 13 33 | }, 34 | "type": "t", 35 | "tail": "no" 36 | } 37 | ], 38 | "notifications": [] 39 | } 40 | -------------------------------------------------------------------------------- /tests/test-dirs/type-enclosing/issue1477.t: -------------------------------------------------------------------------------- 1 | $ cat >test.ml < let g (x : int) = x 3 | > let b = g 1 4 | > EOF 5 | 6 | $ $MERLIN single type-enclosing -position 2:8 \ 7 | > -filename test.ml < test.ml | 8 | > jq '.value' 9 | [ 10 | { 11 | "start": { 12 | "line": 2, 13 | "col": 8 14 | }, 15 | "end": { 16 | "line": 2, 17 | "col": 9 18 | }, 19 | "type": "int -> int", 20 | "tail": "no" 21 | }, 22 | { 23 | "start": { 24 | "line": 2, 25 | "col": 8 26 | }, 27 | "end": { 28 | "line": 2, 29 | "col": 9 30 | }, 31 | "type": "int -> int", 32 | "tail": "no" 33 | }, 34 | { 35 | "start": { 36 | "line": 2, 37 | "col": 8 38 | }, 39 | "end": { 40 | "line": 2, 41 | "col": 11 42 | }, 43 | "type": "int", 44 | "tail": "no" 45 | } 46 | ] 47 | -------------------------------------------------------------------------------- /tests/test-dirs/type-enclosing/issue864.t/issue864.ml: -------------------------------------------------------------------------------- 1 | module X = struct 2 | type t = { z : int } 3 | end 4 | 5 | let f1 _ (x : X.t) = x.z 6 | 7 | let f2 (z : string) (x : X.t) = x.X.z 8 | 9 | let f3 (z : string) (x : X.t) = x.z 10 | -------------------------------------------------------------------------------- /tests/test-dirs/type-enclosing/issueLSP444.t: -------------------------------------------------------------------------------- 1 | From ocaml-lsp#444 (https://github.com/ocaml/ocaml-lsp/issues/444) 2 | $ cat >gadt.ml < type 'a t = 4 | > | A : [\`A] t 5 | > | B : [\`B] t 6 | > 7 | > let f x = 8 | > match x with 9 | > | A -> () 10 | > EOF 11 | 12 | $ $MERLIN single type-enclosing -position 6:9 -verbosity 0 \ 13 | > -filename ./gadt.ml < ./gadt.ml | tr '\r\n' ' ' | jq ".value[0]" 14 | { 15 | "start": { 16 | "line": 6, 17 | "col": 8 18 | }, 19 | "end": { 20 | "line": 6, 21 | "col": 9 22 | }, 23 | "type": "[ `A ] t", 24 | "tail": "no" 25 | } 26 | 27 | $ $MERLIN single type-enclosing -position 7:5 -verbosity 0 \ 28 | > -filename ./gadt.ml < ./gadt.ml | tr '\r\n' ' ' | jq ".value[0]" 29 | { 30 | "start": { 31 | "line": 7, 32 | "col": 4 33 | }, 34 | "end": { 35 | "line": 7, 36 | "col": 5 37 | }, 38 | "type": "[ `A ] t", 39 | "tail": "no" 40 | } 41 | 42 | 43 | $ $MERLIN single errors -verbosity 0 \ 44 | > -filename ./gadt.ml < ./gadt.ml | tr '\r\n' ' ' | jq ".value" 45 | [] 46 | -------------------------------------------------------------------------------- /tests/test-dirs/type-enclosing/issueLSP695.t/main.ml: -------------------------------------------------------------------------------- 1 | (**) 2 | * -------------------------------------------------------------------------------- /tests/test-dirs/type-enclosing/issueLSP695.t/run.t: -------------------------------------------------------------------------------- 1 | FIXME: the file is not empty 2 | $ $MERLIN single document -position 2:0 -filename main.ml -filename ./let.ml < ./let.ml | jq ".value[0:2]" 5 | [ 6 | { 7 | "start": { 8 | "line": 4, 9 | "col": 4 10 | }, 11 | "end": { 12 | "line": 4, 13 | "col": 7 14 | }, 15 | "type": "float", 16 | "tail": "no" 17 | } 18 | ] 19 | -------------------------------------------------------------------------------- /tests/test-dirs/type-enclosing/letop.t/letop.ml: -------------------------------------------------------------------------------- 1 | let (let*) o f = Option.map 2 | 3 | let plus_two tbl key = 4 | let* foo = Hashtbl.find_opt tbl key in 5 | foo + 2 6 | -------------------------------------------------------------------------------- /tests/test-dirs/type-enclosing/letop2.t/letop.ml: -------------------------------------------------------------------------------- 1 | let (let+) x f = Option.map f x 2 | 3 | let (and+) x y = 4 | Option.bind x @@ fun x -> 5 | Option.map (fun y -> (x, y)) y 6 | 7 | let minus_three (tbl1, tbl2) (key1, key2) = 8 | let+ foo = Hashtbl.find_opt tbl1 key1 9 | and+ bar = Hashtbl.find_opt tbl2 key2 10 | and+ man = Hashtbl.find_opt tbl2 key2 in 11 | foo + bar - man 12 | -------------------------------------------------------------------------------- /tests/test-dirs/type-enclosing/letop2.t/run.t: -------------------------------------------------------------------------------- 1 | Various parts of the letop together with andop: 2 | 3 | - The let+ operator: 4 | $ $MERLIN single type-enclosing -position 8:4 -verbosity 0 \ 5 | > -filename ./letop.ml < ./letop.ml | jq ".value[0:2]" 6 | [ 7 | { 8 | "start": { 9 | "line": 8, 10 | "col": 2 11 | }, 12 | "end": { 13 | "line": 8, 14 | "col": 6 15 | }, 16 | "type": "'a option -> ('a -> 'b) -> 'b option", 17 | "tail": "no" 18 | }, 19 | { 20 | "start": { 21 | "line": 8, 22 | "col": 2 23 | }, 24 | "end": { 25 | "line": 8, 26 | "col": 6 27 | }, 28 | "type": "((int * int) * int) option -> ((int * int) * int -> int) -> int option", 29 | "tail": "no" 30 | } 31 | ] 32 | -------------------------------------------------------------------------------- /tests/test-dirs/type-enclosing/merlin-hide.t: -------------------------------------------------------------------------------- 1 | Make sure type-enclosing works properly even when the precise location is not 2 | accessible: 3 | 4 | $ $MERLIN single type-enclosing -position 3:7 -filename hide.ml < module M = struct 6 | > include struct 7 | > let x = 3 8 | > end[@merlin.hide] 9 | > end 10 | > EOF 11 | { 12 | "class": "return", 13 | "value": [ 14 | { 15 | "start": { 16 | "line": 1, 17 | "col": 11 18 | }, 19 | "end": { 20 | "line": 5, 21 | "col": 3 22 | }, 23 | "type": "sig val x : int end", 24 | "tail": "no" 25 | }, 26 | { 27 | "start": { 28 | "line": 1, 29 | "col": 0 30 | }, 31 | "end": { 32 | "line": 5, 33 | "col": 3 34 | }, 35 | "type": "sig val x : int end", 36 | "tail": "no" 37 | } 38 | ], 39 | "notifications": [] 40 | } 41 | -------------------------------------------------------------------------------- /tests/test-dirs/type-enclosing/mod-alias.t/alias.ml: -------------------------------------------------------------------------------- 1 | module L = List 2 | 3 | let _ = L.hd [3] 4 | -------------------------------------------------------------------------------- /tests/test-dirs/type-enclosing/mod-not-in-env.t/not-in-env.ml: -------------------------------------------------------------------------------- 1 | module N = struct 2 | let y = 4 3 | end 4 | 5 | let z = N.x 6 | 7 | let w = N.N 8 | -------------------------------------------------------------------------------- /tests/test-dirs/type-enclosing/mod-type.t/module_type.mli: -------------------------------------------------------------------------------- 1 | module type T = sig type a end 2 | 3 | module T : sig type b end 4 | 5 | include T 6 | 7 | include module type of T 8 | -------------------------------------------------------------------------------- /tests/test-dirs/type-enclosing/objects.t/test.ml: -------------------------------------------------------------------------------- 1 | let s = object 2 | val mutable v = [0; 2] 3 | 4 | method pop = 5 | match v with 6 | | hd :: tl -> 7 | v <- tl; 8 | Some hd 9 | | [] -> None 10 | 11 | method push hd = v <- hd :: v 12 | end 13 | 14 | let r = s#push 3 15 | 16 | let poly obj = obj#pouet "a" 17 | 18 | let nopoly (obj : < pouet : string -> 'a>) = obj#pouet "a" 19 | 20 | class virtual foobar = object 21 | method virtual virtu : string -> char -> int 22 | val virtual virt_avl : string -> char -> int 23 | end 24 | -------------------------------------------------------------------------------- /tests/test-dirs/type-enclosing/record.t/record.ml: -------------------------------------------------------------------------------- 1 | type t = { mutable b: float } 2 | 3 | let b = 10 4 | let x = { b = 9. } 5 | 6 | let y = { c = 9. } 7 | 8 | let _ = x.b <- 3. 9 | 10 | type foo = Bar of {baz : unit} 11 | 12 | let z = Bar ({ baz = () }) 13 | -------------------------------------------------------------------------------- /tests/test-dirs/type-enclosing/types.t/types.ml: -------------------------------------------------------------------------------- 1 | let x = 3 2 | 3 | type x = Foo 4 | 5 | let foo : x = Foo 6 | 7 | type 'a t = 'a 8 | 9 | type 'a s = 'a t 10 | 11 | type 'a l = 'a list 12 | 13 | module M = struct 14 | type 'a t = 'a 15 | end 16 | 17 | type 'a v = Foo of 'a -------------------------------------------------------------------------------- /tests/test-dirs/type-enclosing/variants.t/variants.ml: -------------------------------------------------------------------------------- 1 | type core = [ `A | `B ] 2 | type more = [ core | `C ] 3 | 4 | let x : more = `A 5 | let y : core = `B 6 | 7 | let () = match x with 8 | | `C -> () 9 | | #core -> () 10 | -------------------------------------------------------------------------------- /tests/test-dirs/type-enclosing/verbosity_smart.t/test.ml: -------------------------------------------------------------------------------- 1 | module type T = sig 2 | val u : unit 3 | end 4 | 5 | module M = struct 6 | let u = () 7 | end 8 | 9 | module F () : T = struct 10 | let u = () 11 | end 12 | 13 | module MA = M 14 | 15 | module FT = F () 16 | -------------------------------------------------------------------------------- /tests/test-dirs/type-expr.t/test.ml: -------------------------------------------------------------------------------- 1 | let x = 5 2 | let y = 10 3 | type t = T 4 | module M = List 5 | module type MT = module type of List 6 | let z = () 7 | -------------------------------------------------------------------------------- /tests/test-dirs/with-cmi.t: -------------------------------------------------------------------------------- 1 | Since OCaml 5.1 the compiler support the -cmi-file flag: 2 | > -cmi-file filename 3 | > Use the given interface file to type-check the ML source file to compile. 4 | > When this option is not specified, the compiler looks for a .mli file with 5 | > the same base name than the implementation it is compiling and in the same 6 | > directory. If such a file is found, the compiler looks for a corresponding 7 | > .cmi file in the included directories and reports an error if it fails to 8 | > find one. 9 | 10 | $ cat >main.mli <<'EOF' 11 | > val f : unit -> int 12 | > EOF 13 | 14 | $ $OCAMLC -c main.mli 15 | $ rm main.mli 16 | 17 | 18 | $ cat >main.ml <<'EOF' 19 | > let f () = 42 20 | > EOF 21 | 22 | $ $OCAMLC -c -cmi-file main.cmi main.ml 23 | 24 | Merlin should ignore the -cmi-file flag 25 | $ $MERLIN single errors -cmi-file main.cmi -filename main.ml jq '.value' 27 | [] 28 | -------------------------------------------------------------------------------- /tests/test-dirs/with-ppx/dune: -------------------------------------------------------------------------------- 1 | (cram 2 | (applies_to :whole_subtree) 3 | (locks ../server-tests/merlin_server)) 4 | 5 | (cram 6 | (applies_to :whole_subtree) 7 | (enabled_if (= %{env:MERLIN_TESTS=default} all))) 8 | -------------------------------------------------------------------------------- /tests/test-dirs/with-ppx/expand_node.t/c_ppx/dune: -------------------------------------------------------------------------------- 1 | (library 2 | (name c_ppx) 3 | (kind ppx_deriver) 4 | (libraries ppxlib)) 5 | -------------------------------------------------------------------------------- /tests/test-dirs/with-ppx/expand_node.t/rewriter/dune: -------------------------------------------------------------------------------- 1 | (library 2 | (name my_ppx) 3 | (kind ppx_rewriter) 4 | (libraries ppxlib)) 5 | -------------------------------------------------------------------------------- /tests/test-dirs/with-ppx/expand_node.t/rewriter/my_ppx.ml: -------------------------------------------------------------------------------- 1 | open Ppxlib 2 | 3 | let expand ~ctxt payload = 4 | let _p = payload in 5 | let loc = Expansion_context.Extension.extension_point_loc ctxt in 6 | Ast_builder.Default.estring ~loc "OCaml is so cool" 7 | 8 | let my_extension = 9 | Extension.V3.declare "tell_me" Extension.Context.expression 10 | Ast_pattern.(__) 11 | expand 12 | 13 | let rule = Ppxlib.Context_free.Rule.extension my_extension 14 | let () = Driver.register_transformation ~rules:[ rule ] "tell_me" 15 | -------------------------------------------------------------------------------- /tests/test-dirs/with-ppx/issue1660-deriving-compare.t: -------------------------------------------------------------------------------- 1 | $ cat >dune-project < (lang dune 2.0) 3 | > EOF 4 | 5 | $ cat >main.ml < module M = struct 7 | > type t = 8 | > | Foo 9 | > | Bar 10 | > end 11 | > EOF 12 | 13 | $ $MERLIN single type-enclosing -position 2:7 \ 14 | > -filename main.ml < main.ml | jq '.value[0].type' 15 | "type t = Foo | Bar" 16 | 17 | 18 | $ cat >main.ml < module M = struct 20 | > type t = 21 | > | Foo 22 | > | Bar 23 | > [@@deriving compare] 24 | > end 25 | > EOF 26 | 27 | $ cat >dune < (library 29 | > (name main) 30 | > (preprocess (pps ppx_compare))) 31 | > EOF 32 | 33 | $ dune build 34 | 35 | $ $MERLIN single type-enclosing -position 2:7 \ 36 | > -filename main.ml < main.ml | jq '.value[0].type' 37 | "type t = Foo | Bar" 38 | -------------------------------------------------------------------------------- /tests/test-dirs/with-ppx/parsetree-cache.t/dune: -------------------------------------------------------------------------------- 1 | (library 2 | (name my_ppx) 3 | (kind ppx_rewriter) 4 | (modules my_ppx) 5 | (libraries ppxlib)) 6 | 7 | (executable 8 | (name main) 9 | (modules main) 10 | (preprocess 11 | (pps my_ppx)) 12 | (preprocessor_deps 13 | (file ppx_dep.txt))) 14 | -------------------------------------------------------------------------------- /tests/test-dirs/with-ppx/parsetree-cache.t/dune-project: -------------------------------------------------------------------------------- 1 | (lang dune 2.0) 2 | -------------------------------------------------------------------------------- /tests/test-dirs/with-ppx/typed-holes.t/dune: -------------------------------------------------------------------------------- 1 | (executable 2 | (name main) 3 | (preprocess 4 | (pps my_ppx))) 5 | -------------------------------------------------------------------------------- /tests/test-dirs/with-ppx/typed-holes.t/dune-project: -------------------------------------------------------------------------------- 1 | (lang dune 2.0) 2 | -------------------------------------------------------------------------------- /tests/test-dirs/with-ppx/typed-holes.t/rewriter/dune: -------------------------------------------------------------------------------- 1 | (library 2 | (name my_ppx) 3 | (kind ppx_rewriter) 4 | (libraries ppxlib)) 5 | -------------------------------------------------------------------------------- /tests/test-dirs/with-ppx/typed-holes.t/rewriter/my_ppx.ml: -------------------------------------------------------------------------------- 1 | open Ppxlib 2 | 3 | let expand ~ctxt payload = 4 | let loc = Expansion_context.Extension.extension_point_loc ctxt in 5 | Ast_builder.Default.eint ~loc payload 6 | 7 | let my_extension = 8 | Extension.V3.declare "get_int" Extension.Context.expression 9 | Ast_pattern.(single_expr_payload (eint __)) 10 | expand 11 | 12 | let rule = Ppxlib.Context_free.Rule.extension my_extension 13 | let () = Driver.register_transformation ~rules:[ rule ] "get_int" 14 | -------------------------------------------------------------------------------- /tests/test-dirs/with-ppx/typed-holes.t/run.t: -------------------------------------------------------------------------------- 1 | The ppx works as expected without any typed-hole: 2 | $ cat >main.ml < match Some 3 with 4 | > | None -> () 5 | > | Some _ -> print_int [%get_int 42] 6 | > EOF 7 | 8 | $ dune exec ./main.exe 2>/dev/null 9 | 42 10 | 11 | $ $MERLIN single errors \ 12 | > -filename main.ml < main.ml 13 | { 14 | "class": "return", 15 | "value": [], 16 | "notifications": [] 17 | } 18 | 19 | and with type-holes (since #1503) 20 | $ cat >main.ml < match Some 3 with 22 | > | None -> _ 23 | > | Some _ -> print_int [%get_int 42] 24 | > EOF 25 | 26 | $ $MERLIN single errors \ 27 | > -filename main.ml < main.ml 28 | { 29 | "class": "return", 30 | "value": [], 31 | "notifications": [] 32 | } 33 | -------------------------------------------------------------------------------- /tests/test-units/sherldoc/dune: -------------------------------------------------------------------------------- 1 | (test 2 | (name sherlodoc_test) 3 | (package merlin-lib) 4 | (libraries fmt alcotest merlin-lib.sherlodoc)) 5 | -------------------------------------------------------------------------------- /tests/test-units/sherldoc/name_cost_test.mli: -------------------------------------------------------------------------------- 1 | val cases : string * unit Alcotest.test_case list 2 | -------------------------------------------------------------------------------- /tests/test-units/sherldoc/query_test.mli: -------------------------------------------------------------------------------- 1 | val cases : string * unit Alcotest.test_case list 2 | -------------------------------------------------------------------------------- /tests/test-units/sherldoc/sherlodoc_test.ml: -------------------------------------------------------------------------------- 1 | let () = 2 | Alcotest.run "merlin-lib.sherlodoc" 3 | [ Type_expr_test.cases; 4 | Name_cost_test.cases; 5 | Type_distance_test.cases; 6 | Query_test.cases 7 | ] 8 | -------------------------------------------------------------------------------- /tests/test-units/sherldoc/type_distance_test.mli: -------------------------------------------------------------------------------- 1 | val cases : string * unit Alcotest.test_case list 2 | -------------------------------------------------------------------------------- /tests/test-units/sherldoc/type_expr_test.mli: -------------------------------------------------------------------------------- 1 | val cases : string * unit Alcotest.test_case list 2 | -------------------------------------------------------------------------------- /upstream/gen_patch.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | D_MERLIN=../src/ocaml 4 | 5 | FROM=503 6 | TO=503 7 | 8 | D_FROM=ocaml_${FROM} 9 | D_TO=ocaml_${TO} 10 | D_PATCH=patches__${TO} 11 | 12 | mkdir "${D_PATCH}" 13 | 14 | for file in "${D_TO}"/*/*.ml*; do 15 | F_TO=${file} 16 | F_FROM=$(echo "${F_TO}" | sed "s/${D_TO}/${D_FROM}/g") 17 | F_MERLIN=$(echo "${F_TO}" | sed "s,${D_TO},${D_MERLIN},g") 18 | F_PATCH=$(echo "${F_TO}" | sed "s/${D_TO}/${D_PATCH}/g") 19 | mkdir "$(dirname "${F_PATCH}")" 2>/dev/null | true 20 | # Make diff 21 | if [ "$F_FROM" = "$F_TO" ]; then 22 | git diff "${F_FROM}" >"${F_PATCH}.patch" 23 | else 24 | diff -u -N "${F_FROM}" "${F_TO}" >"${F_PATCH}.patch" 25 | fi 26 | if [ -s "${F_PATCH}.patch" ]; then 27 | # Apply the patch file 28 | patch --no-backup-if-mismatch --merge "${F_MERLIN}" "${F_PATCH}.patch" 29 | echo "patched ${F_MERLIN}" 30 | else 31 | rm "${F_PATCH}.patch" 32 | fi 33 | done 34 | -------------------------------------------------------------------------------- /upstream/ocaml_414/base-rev.txt: -------------------------------------------------------------------------------- 1 | 87efa5e6681dd0fc6547ef4669883bf15c871588 2 | -------------------------------------------------------------------------------- /upstream/ocaml_414/utils/int_replace_polymorphic_compare.ml: -------------------------------------------------------------------------------- 1 | let ( = ) : int -> int -> bool = Stdlib.( = ) 2 | let ( <> ) : int -> int -> bool = Stdlib.( <> ) 3 | let ( < ) : int -> int -> bool = Stdlib.( < ) 4 | let ( > ) : int -> int -> bool = Stdlib.( > ) 5 | let ( <= ) : int -> int -> bool = Stdlib.( <= ) 6 | let ( >= ) : int -> int -> bool = Stdlib.( >= ) 7 | 8 | let compare : int -> int -> int = Stdlib.compare 9 | -------------------------------------------------------------------------------- /upstream/ocaml_414/utils/int_replace_polymorphic_compare.mli: -------------------------------------------------------------------------------- 1 | val ( = ) : int -> int -> bool 2 | val ( <> ) : int -> int -> bool 3 | val ( < ) : int -> int -> bool 4 | val ( > ) : int -> int -> bool 5 | val ( <= ) : int -> int -> bool 6 | val ( >= ) : int -> int -> bool 7 | 8 | val compare : int -> int -> int 9 | -------------------------------------------------------------------------------- /upstream/ocaml_500/base-rev.txt: -------------------------------------------------------------------------------- 1 | e86f9e5d41217e8c824455206e854072b803b170 2 | -------------------------------------------------------------------------------- /upstream/ocaml_500/utils/int_replace_polymorphic_compare.ml: -------------------------------------------------------------------------------- 1 | let ( = ) : int -> int -> bool = Stdlib.( = ) 2 | let ( <> ) : int -> int -> bool = Stdlib.( <> ) 3 | let ( < ) : int -> int -> bool = Stdlib.( < ) 4 | let ( > ) : int -> int -> bool = Stdlib.( > ) 5 | let ( <= ) : int -> int -> bool = Stdlib.( <= ) 6 | let ( >= ) : int -> int -> bool = Stdlib.( >= ) 7 | 8 | let compare : int -> int -> int = Stdlib.compare 9 | -------------------------------------------------------------------------------- /upstream/ocaml_500/utils/int_replace_polymorphic_compare.mli: -------------------------------------------------------------------------------- 1 | val ( = ) : int -> int -> bool 2 | val ( <> ) : int -> int -> bool 3 | val ( < ) : int -> int -> bool 4 | val ( > ) : int -> int -> bool 5 | val ( <= ) : int -> int -> bool 6 | val ( >= ) : int -> int -> bool 7 | 8 | val compare : int -> int -> int 9 | -------------------------------------------------------------------------------- /upstream/ocaml_501/base-rev.txt: -------------------------------------------------------------------------------- 1 | 35fdd0226e2e05a1a8244ecfec780b563b23b59c 2 | -------------------------------------------------------------------------------- /upstream/ocaml_501/utils/int_replace_polymorphic_compare.ml: -------------------------------------------------------------------------------- 1 | let ( = ) : int -> int -> bool = Stdlib.( = ) 2 | let ( <> ) : int -> int -> bool = Stdlib.( <> ) 3 | let ( < ) : int -> int -> bool = Stdlib.( < ) 4 | let ( > ) : int -> int -> bool = Stdlib.( > ) 5 | let ( <= ) : int -> int -> bool = Stdlib.( <= ) 6 | let ( >= ) : int -> int -> bool = Stdlib.( >= ) 7 | 8 | let compare : int -> int -> int = Stdlib.compare 9 | -------------------------------------------------------------------------------- /upstream/ocaml_501/utils/int_replace_polymorphic_compare.mli: -------------------------------------------------------------------------------- 1 | val ( = ) : int -> int -> bool 2 | val ( <> ) : int -> int -> bool 3 | val ( < ) : int -> int -> bool 4 | val ( > ) : int -> int -> bool 5 | val ( <= ) : int -> int -> bool 6 | val ( >= ) : int -> int -> bool 7 | 8 | val compare : int -> int -> int 9 | -------------------------------------------------------------------------------- /upstream/ocaml_502/base-rev.txt: -------------------------------------------------------------------------------- 1 | dfe59502ad2e115882296416afc4cfd814821572 2 | -------------------------------------------------------------------------------- /upstream/ocaml_502/utils/int_replace_polymorphic_compare.ml: -------------------------------------------------------------------------------- 1 | let ( = ) : int -> int -> bool = Stdlib.( = ) 2 | let ( <> ) : int -> int -> bool = Stdlib.( <> ) 3 | let ( < ) : int -> int -> bool = Stdlib.( < ) 4 | let ( > ) : int -> int -> bool = Stdlib.( > ) 5 | let ( <= ) : int -> int -> bool = Stdlib.( <= ) 6 | let ( >= ) : int -> int -> bool = Stdlib.( >= ) 7 | 8 | let compare : int -> int -> int = Stdlib.compare 9 | -------------------------------------------------------------------------------- /upstream/ocaml_502/utils/int_replace_polymorphic_compare.mli: -------------------------------------------------------------------------------- 1 | val ( = ) : int -> int -> bool 2 | val ( <> ) : int -> int -> bool 3 | val ( < ) : int -> int -> bool 4 | val ( > ) : int -> int -> bool 5 | val ( <= ) : int -> int -> bool 6 | val ( >= ) : int -> int -> bool 7 | 8 | val compare : int -> int -> int 9 | -------------------------------------------------------------------------------- /upstream/ocaml_503/base-rev.txt: -------------------------------------------------------------------------------- 1 | bc5083c1d3b773fc3198355494afd2fb4628ff0e 2 | -------------------------------------------------------------------------------- /upstream/ocaml_503/utils/int_replace_polymorphic_compare.ml: -------------------------------------------------------------------------------- 1 | let ( = ) : int -> int -> bool = Stdlib.( = ) 2 | let ( <> ) : int -> int -> bool = Stdlib.( <> ) 3 | let ( < ) : int -> int -> bool = Stdlib.( < ) 4 | let ( > ) : int -> int -> bool = Stdlib.( > ) 5 | let ( <= ) : int -> int -> bool = Stdlib.( <= ) 6 | let ( >= ) : int -> int -> bool = Stdlib.( >= ) 7 | 8 | let compare : int -> int -> int = Stdlib.compare 9 | -------------------------------------------------------------------------------- /upstream/ocaml_503/utils/int_replace_polymorphic_compare.mli: -------------------------------------------------------------------------------- 1 | val ( = ) : int -> int -> bool 2 | val ( <> ) : int -> int -> bool 3 | val ( < ) : int -> int -> bool 4 | val ( > ) : int -> int -> bool 5 | val ( <= ) : int -> int -> bool 6 | val ( >= ) : int -> int -> bool 7 | 8 | val compare : int -> int -> int 9 | -------------------------------------------------------------------------------- /vim/merlin/autoload/neomake/makers/ft/ocaml.vim: -------------------------------------------------------------------------------- 1 | function! neomake#makers#ft#ocaml#EnabledMakers() abort 2 | return ['merlin'] 3 | endfunction 4 | 5 | function! neomake#makers#ft#ocaml#merlin() abort 6 | let maker = {} 7 | function! maker.get_list_entries(jobinfo) 8 | return merlin#ErrorLocList() 9 | endfunction 10 | return maker 11 | endfunction 12 | -------------------------------------------------------------------------------- /vim/merlin/ftdetect/merlin.vim: -------------------------------------------------------------------------------- 1 | au BufNewFile,BufRead .merlin set ft=merlin 2 | -------------------------------------------------------------------------------- /vim/merlin/ftplugin/merlin.vim: -------------------------------------------------------------------------------- 1 | setlocal commentstring=#\ %s 2 | setlocal comments=:# 3 | -------------------------------------------------------------------------------- /vim/merlin/ftplugin/ocaml.vim: -------------------------------------------------------------------------------- 1 | " Activate merlin on current buffer 2 | call merlin#Register() 3 | -------------------------------------------------------------------------------- /vim/merlin/ftplugin/ocamlinterface.vim: -------------------------------------------------------------------------------- 1 | " Activate merlin on current buffer 2 | call merlin#Register() 3 | -------------------------------------------------------------------------------- /vim/merlin/ftplugin/ocamllex.vim: -------------------------------------------------------------------------------- 1 | " Activate merlin on current buffer 2 | call merlin#Register() 3 | -------------------------------------------------------------------------------- /vim/merlin/ftplugin/omlet.vim: -------------------------------------------------------------------------------- 1 | " Activate merlin on current buffer 2 | call merlin#Register() 3 | -------------------------------------------------------------------------------- /vim/merlin/ftplugin/reason.vim: -------------------------------------------------------------------------------- 1 | " Activate merlin on current buffer 2 | call merlin#Register() 3 | -------------------------------------------------------------------------------- /vim/merlin/plugin/merlin.vim: -------------------------------------------------------------------------------- 1 | " If the mode didn't work for you, ensure that ocamlmerlin binary can be found 2 | " in PATH. 3 | " Most commands are accessible only from omlet/ocaml buffers, check from an 4 | " appropriate buffer if merlin.vim is effectively loaded. 5 | 6 | " If you are using syntastic and don't want warnings notified, set the following 7 | " variable to "true" 8 | 9 | if !exists('g:merlin') | let g:merlin = {} | endif | let s:c = g:merlin 10 | let g:merlin_ignore_warnings = "false" 11 | 12 | let s:c.merlin_home = expand(':h:h:h:h') 13 | let s:c.merlin_parent = expand(':h:h:h:h:h') 14 | 15 | " Highlight the expression which type is given 16 | hi def link EnclosingExpr IncSearch 17 | -------------------------------------------------------------------------------- /vim/merlin/syntax/merlin.vim: -------------------------------------------------------------------------------- 1 | " Vim syntax file for editing merlin project files 2 | if exists("b:current_syntax") 3 | finish 4 | endif 5 | 6 | syn keyword merlinKeyword S B SUFFIX PKG REC EXT PRJ FLG CMI CMT 7 | syn match merlinComment "\v#.*$" 8 | 9 | hi link merlinKeyword Keyword 10 | hi link merlinComment Comment 11 | 12 | let b:current_syntax = "merlin" 13 | 14 | -------------------------------------------------------------------------------- /vim/merlin/syntax_checkers/ocaml/merlin.vim: -------------------------------------------------------------------------------- 1 | " Enable Syntastic support 2 | " Make sure syntax_checkers directory is on runtime path, then set 3 | " :let g:syntastic_ocaml_checkers=['merlin'] 4 | 5 | function! SyntaxCheckers_ocaml_merlin_IsAvailable() 6 | if !exists("*merlin#SelectBinary") 7 | return 0 8 | endif 9 | try 10 | let l:path = merlin#SelectBinary() 11 | return executable(l:path) 12 | catch 13 | return 0 14 | endtry 15 | endfunction 16 | 17 | function! SyntaxCheckers_ocaml_merlin_GetLocList() 18 | return merlin#ErrorLocList() 19 | endfunction 20 | 21 | call g:SyntasticRegistry.CreateAndRegisterChecker({ 22 | \ 'filetype': 'ocaml', 23 | \ 'name': 'merlin'}) 24 | -------------------------------------------------------------------------------- /vim/merlin/syntax_checkers/ocamlinterface/merlin.vim: -------------------------------------------------------------------------------- 1 | " Enable Syntastic support 2 | " Make sure syntax_checkers directory is on runtime path, then set 3 | " :let g:syntastic_ocamlinterface_checkers=['merlin'] 4 | 5 | function! SyntaxCheckers_ocamlinterface_merlin_IsAvailable() 6 | if !exists("*merlin#SelectBinary") 7 | return 0 8 | endif 9 | try 10 | let l:path = merlin#SelectBinary() 11 | return executable(l:path) 12 | catch 13 | return 0 14 | endtry 15 | endfunction 16 | 17 | function! SyntaxCheckers_ocamlinterface_merlin_GetLocList() 18 | return merlin#ErrorLocList() 19 | endfunction 20 | 21 | call g:SyntasticRegistry.CreateAndRegisterChecker({ 22 | \ 'filetype': 'ocamlinterface', 23 | \ 'name': 'merlin'}) 24 | -------------------------------------------------------------------------------- /vim/merlin/syntax_checkers/omlet/merlin.vim: -------------------------------------------------------------------------------- 1 | " Enable Syntastic support for omlet mode 2 | " Make sure syntax_checkers directory is on runtime path, then set 3 | " :let g:syntastic_omlet_checkers=['merlin'] 4 | 5 | function! SyntaxCheckers_omlet_merlin_IsAvailable() 6 | if !exists("*merlin#SelectBinary") 7 | return 0 8 | endif 9 | try 10 | let l:path = merlin#SelectBinary() 11 | return executable(l:path) 12 | catch 13 | return 0 14 | endtry 15 | endfunction 16 | 17 | function! SyntaxCheckers_omlet_merlin_GetLocList() 18 | return merlin#ErrorLocList() 19 | endfunction 20 | 21 | call g:SyntasticRegistry.CreateAndRegisterChecker({ 22 | \ 'filetype': 'omlet', 23 | \ 'name': 'merlin'}) 24 | --------------------------------------------------------------------------------