├── tests ├── test-dirs │ ├── .merlin │ ├── no-escape.t │ │ ├── foo.cmi │ │ ├── test_use.ml │ │ └── test_open.ml │ ├── config │ │ ├── symlinks.t │ │ │ └── real │ │ │ │ └── main.ml │ │ ├── workdir.t │ │ │ └── src │ │ │ │ └── main.ml │ │ ├── flags │ │ │ ├── dune │ │ │ ├── invalid.t │ │ │ └── nolabels.t │ │ ├── check │ │ │ ├── dune │ │ │ └── check-config.t │ │ ├── dot-merlin-reader │ │ │ ├── dune │ │ │ └── erroneous-config.t │ │ ├── dune │ │ └── path-expansion.t │ │ │ └── run.t │ ├── deprecation.t │ │ ├── x.ml │ │ ├── foo.mli │ │ └── run.t │ ├── issue1322.t │ │ ├── .merlin │ │ ├── foo.ml │ │ ├── nasty.ml │ │ └── run.t │ ├── server-tests │ │ ├── typer-cache │ │ │ ├── load_path.t │ │ │ │ ├── sub │ │ │ │ │ └── dep.ml │ │ │ │ └── test.ml │ │ │ ├── sub.t │ │ │ │ └── test.ml │ │ │ ├── dune │ │ │ ├── stamps.t │ │ │ │ └── run.t │ │ │ └── current-level.t │ │ │ │ └── run.t │ │ └── dune │ ├── alerts.t │ │ ├── main.ml │ │ ├── lib.mli │ │ └── run.t │ ├── completion │ │ ├── expansion.t │ │ │ ├── expansion1.ml │ │ │ └── expansion2.ml │ │ ├── kind.t │ │ │ └── test.ml │ │ ├── application_context.t │ │ │ ├── application_context.ml │ │ │ └── run.t │ │ ├── disambiguation.t │ │ │ ├── constr.ml │ │ │ └── record.ml │ │ ├── infix.t │ │ │ ├── infix.ml │ │ │ └── run.t │ │ └── parenthesize.t │ │ │ ├── parenthesize.ml │ │ │ └── run.t │ ├── locate │ │ ├── includes.t │ │ │ ├── foo.ml │ │ │ ├── test.ml │ │ │ └── run.t │ │ ├── non-local │ │ │ ├── preference.t │ │ │ │ ├── a.ml │ │ │ │ ├── b.mli │ │ │ │ ├── a.mli │ │ │ │ └── b.ml │ │ │ ├── ignore-kept-locs.t │ │ │ │ ├── a.ml │ │ │ │ └── b.ml │ │ │ └── dune │ │ ├── module-aliases.t │ │ │ ├── dune-project │ │ │ ├── dune │ │ │ ├── anothermod.ml │ │ │ ├── anothermod.mli │ │ │ └── main.ml │ │ ├── in-generated-file.t │ │ │ ├── dune-project │ │ │ └── main.ml │ │ ├── looping-substitution.t │ │ │ ├── foo.ml │ │ │ ├── test.ml │ │ │ ├── bar.ml │ │ │ └── run.t │ │ ├── issue802.t │ │ │ ├── mylib__.ml │ │ │ ├── error.ml │ │ │ └── a.ml │ │ ├── context-detection │ │ │ ├── cd-mod_constr.t │ │ │ │ ├── mod_constr.ml │ │ │ │ └── run.t │ │ │ ├── dune │ │ │ ├── cd-from_a_pattern.t │ │ │ │ ├── from_a_pattern.ml │ │ │ │ └── run.t │ │ │ ├── cd-label.t │ │ │ │ ├── label.ml │ │ │ │ └── run.t │ │ │ ├── cd-field.t │ │ │ │ ├── field.ml │ │ │ │ └── run.t │ │ │ └── cd-test.t │ │ │ │ └── test.ml │ │ ├── issue845.t │ │ │ ├── local_map.ml │ │ │ ├── local_map.mli │ │ │ └── run.t │ │ ├── ambiguity │ │ │ ├── dune │ │ │ ├── rebinding.t │ │ │ │ ├── rebinding.ml │ │ │ │ └── run.t │ │ │ └── not-in-env.t │ │ ├── issue949.t │ │ │ ├── issue949.ml │ │ │ └── run.t │ │ ├── local-definitions │ │ │ ├── dune │ │ │ ├── issue806.t │ │ │ │ ├── issue806.ml │ │ │ │ └── run.t │ │ │ └── issue798.t │ │ │ │ ├── issue798.ml │ │ │ │ └── run.t │ │ ├── reconstruct-identifier │ │ │ ├── dune │ │ │ ├── off_by_one.t │ │ │ │ ├── off_by_one.ml │ │ │ │ └── run.t │ │ │ └── newlines.t │ │ │ │ ├── escaped_newline.ml │ │ │ │ ├── newline_in_quotes.ml │ │ │ │ └── run.t │ │ ├── mutually-recursive.t │ │ │ ├── issue973.ml │ │ │ └── run.t │ │ ├── issue1398.t │ │ │ ├── issue1398.ml │ │ │ └── run.t │ │ ├── functors │ │ │ ├── dune │ │ │ ├── f-missed_shadowing.t │ │ │ │ ├── missed_shadowing.ml │ │ │ │ └── run.t │ │ │ ├── f-generative.t │ │ │ │ ├── generative.ml │ │ │ │ └── run.t │ │ │ ├── f-all_local.t │ │ │ │ └── all_local.ml │ │ │ ├── f-from_application.t │ │ │ │ ├── from_application.ml │ │ │ │ └── run.t │ │ │ ├── f-included.t │ │ │ │ ├── run.t │ │ │ │ └── included.ml │ │ │ ├── f-nested_applications.t │ │ │ │ └── nested_applications.ml │ │ │ └── f-test-ml-mli.t │ │ ├── sig-substs.t │ │ │ ├── basic.ml │ │ │ └── run.t │ │ ├── predef.t │ │ ├── dune │ │ ├── with-holes.t │ │ │ └── run.t │ │ ├── issue1199.t │ │ └── issue1424.t │ ├── document │ │ ├── src-documentation.t │ │ │ ├── dune-project │ │ │ ├── dune │ │ │ └── run.t │ │ ├── dune │ │ ├── unattached-comment.t │ │ └── module-doc.t │ ├── locate-type.t │ │ ├── b.ml │ │ ├── a.ml │ │ └── run.t │ ├── construct │ │ ├── dune │ │ ├── c-modules.t │ │ │ ├── functor_app.ml │ │ │ └── module.ml │ │ ├── c-parenthesis.t │ │ └── holes.t │ ├── short-paths.t │ │ ├── dep.mli │ │ └── test.ml │ ├── type-enclosing │ │ ├── mod-alias.t │ │ │ └── alias.ml │ │ ├── issue1116.t │ │ │ ├── issue1116.ml │ │ │ └── run.t │ │ ├── let.t │ │ │ ├── let.ml │ │ │ └── run.t │ │ ├── github1003.t │ │ │ ├── issue1003.ml │ │ │ └── run.t │ │ ├── mod-not-in-env.t │ │ │ ├── not-in-env.ml │ │ │ └── run.t │ │ ├── letop.t │ │ │ └── letop.ml │ │ ├── mod-type.t │ │ │ └── module_type.mli │ │ ├── variants.t │ │ │ └── variants.ml │ │ ├── issue864.t │ │ │ └── issue864.ml │ │ ├── record.t │ │ │ └── record.ml │ │ ├── types.t │ │ │ └── types.ml │ │ ├── constructors_and_paths.t │ │ │ └── cons.ml │ │ ├── objects.t │ │ │ └── test.ml │ │ ├── issue1226.t │ │ ├── merlin-hide.t │ │ ├── issueLSP444.t │ │ └── issue1278.t │ ├── destruct │ │ ├── dune │ │ ├── issue596.t │ │ └── issue1300.t │ ├── outline.t │ │ ├── path.ml │ │ └── foo.ml │ ├── issue1109.t │ │ ├── issue1109.ml │ │ └── run.t │ ├── pp │ │ ├── dune │ │ └── simple-pp.t │ ├── occurrences │ │ ├── issue827.t │ │ │ └── issue827.ml │ │ ├── issue1398.t │ │ │ └── issue1398.ml │ │ ├── dune │ │ ├── basic.t │ │ │ └── basic.ml │ │ ├── pattern.t │ │ ├── issue1410.t │ │ └── occ-types.t │ ├── type-expr.t │ │ └── test.ml │ ├── environment_on_open.t │ │ ├── environment_on_open.ml │ │ └── run.t │ ├── errors │ │ ├── error-in-constrained-env.t │ │ │ ├── test.ml │ │ │ └── run.t │ │ ├── typing-after-parsing.t │ │ │ └── test.ml │ │ ├── error-node-line-break.t │ │ └── issue1222.t │ ├── dune │ ├── misc │ │ ├── external-arity.t │ │ └── load_path.t │ ├── motion │ │ ├── phrase.t │ │ └── jump.t │ └── refactor-open │ │ ├── qualify_short_paths.t │ │ ├── functor-app.t │ │ └── test.ml │ │ └── record_field.t ├── dune └── merlin-wrapper ├── src ├── frontend │ ├── ocamlmerlin │ │ ├── old │ │ │ └── old_merlin.mli │ │ ├── new │ │ │ └── new_commands.mli │ │ ├── gen_ccflags.ml │ │ └── dune │ ├── dune │ └── query_commands.mli ├── kernel │ ├── mppx.mli │ ├── dune │ ├── mreader_extend.mli │ ├── mocaml.mli │ ├── mpipeline.mli │ ├── msource.mli │ ├── mreader.mli │ ├── mtyper.mli │ └── mreader_recover.mli ├── ocaml │ ├── preprocess │ │ ├── explain │ │ │ └── dune │ │ ├── printer │ │ │ └── dune │ │ ├── recover │ │ │ ├── dune │ │ │ ├── emitter.mli │ │ │ ├── recovery.mli │ │ │ ├── recover_attrib.mli │ │ │ ├── synthesis.mli │ │ │ └── compressedBitSet.mli │ │ ├── parser_printer.mli │ │ ├── parser_recover.mli │ │ ├── dune │ │ └── lexer_ident.mli │ ├── utils │ │ ├── dune │ │ ├── directory_content_cache.ml │ │ ├── lazy_backtrack.mli │ │ ├── clflags.ml │ │ └── clflags.mli │ ├── parsing │ │ ├── msupport_parsing.ml │ │ └── dune │ ├── typing │ │ ├── saved_parts.mli │ │ ├── dune │ │ ├── saved_parts.ml │ │ ├── short_paths.mli │ │ ├── includemod_errorprinter.mli │ │ ├── rec_check.mli │ │ ├── typedecl_unboxed.mli │ │ ├── annot.mli │ │ ├── printtyped.mli │ │ └── printpat.mli │ └── merlin_specific │ │ └── dune ├── platform │ ├── dune │ └── os_ipc.ml ├── dot-protocol │ └── dune ├── analysis │ ├── refactor_open.mli │ ├── construct.mli │ ├── expansion.mli │ ├── dune │ ├── namespaced_path.mli │ └── ptyp_of_type.mli ├── dot-merlin │ └── dune ├── utils │ ├── dune │ ├── file_id.mli │ ├── sexp.mli │ └── file_id.ml ├── extend │ ├── dune │ ├── .gitignore │ ├── extend_driver.mli │ └── extend_main.mli └── config │ ├── dune │ └── gen_config.ml ├── upstream ├── ocaml_413 │ ├── base-rev.txt │ ├── utils │ │ ├── int_replace_polymorphic_compare.mli │ │ ├── int_replace_polymorphic_compare.ml │ │ ├── domainstate.mli.c │ │ ├── binutils.mli │ │ └── terminfo.mli │ ├── parsing │ │ ├── VIPs.md │ │ └── ast_invariants.mli │ └── typing │ │ ├── includemod_errorprinter.mli │ │ ├── rec_check.mli │ │ ├── annot.mli │ │ ├── printtyped.mli │ │ ├── typedecl_unboxed.mli │ │ └── printpat.mli └── ocaml_414 │ ├── base-rev.txt │ ├── utils │ ├── int_replace_polymorphic_compare.mli │ ├── int_replace_polymorphic_compare.ml │ ├── domainstate.mli.c │ ├── binutils.mli │ └── terminfo.mli │ ├── typing │ ├── includemod_errorprinter.mli │ ├── rec_check.mli │ ├── typedecl_unboxed.mli │ ├── annot.mli │ ├── printtyped.mli │ └── printpat.mli │ └── parsing │ └── ast_invariants.mli ├── vim └── merlin │ ├── ftdetect │ └── merlin.vim │ ├── ftplugin │ ├── merlin.vim │ ├── ocaml.vim │ ├── omlet.vim │ └── reason.vim │ ├── autoload │ └── neomake │ │ └── makers │ │ └── ft │ │ └── ocaml.vim │ ├── syntax │ └── merlin.vim │ ├── syntax_checkers │ ├── ocaml │ │ └── merlin.vim │ └── omlet │ │ └── merlin.vim │ ├── plugin │ └── merlin.vim │ └── dune ├── dune-project ├── .gitignore ├── .gitattributes ├── Makefile ├── emacs ├── dune └── merlin-xref.el ├── dot-merlin-reader.opam ├── doc ├── next │ ├── merlin.wiki │ └── Protocol.wiki └── dev │ └── SERVER.md ├── dune-release.sh ├── appveyor ├── findlib-1.7.3.patch └── easy-format-1.2.0.patch ├── appveyor.yml ├── merlin-lib.opam ├── .github └── workflows │ └── emacs-lint.yml ├── LICENSE └── appveyor.cmd /tests/test-dirs/.merlin: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test-dirs/no-escape.t/foo.cmi: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test-dirs/config/symlinks.t/real/main.ml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test-dirs/deprecation.t/x.ml: -------------------------------------------------------------------------------- 1 | let x = Foo.ba 2 | -------------------------------------------------------------------------------- /tests/test-dirs/no-escape.t/test_use.ml: -------------------------------------------------------------------------------- 1 | open Foo 2 | -------------------------------------------------------------------------------- /tests/test-dirs/issue1322.t/.merlin: -------------------------------------------------------------------------------- 1 | FLG -short-paths 2 | -------------------------------------------------------------------------------- /tests/test-dirs/server-tests/typer-cache/load_path.t/sub/dep.ml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/test-dirs/alerts.t/main.ml: -------------------------------------------------------------------------------- 1 | open Lib 2 | let x = sqrt 3. 3 | -------------------------------------------------------------------------------- /tests/test-dirs/completion/expansion.t/expansion1.ml: -------------------------------------------------------------------------------- 1 | let x = L.m 2 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/includes.t/foo.ml: -------------------------------------------------------------------------------- 1 | type 'a t = T of 'a 2 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/non-local/preference.t/a.ml: -------------------------------------------------------------------------------- 1 | let value = 3 2 | -------------------------------------------------------------------------------- /tests/test-dirs/server-tests/typer-cache/sub.t/test.ml: -------------------------------------------------------------------------------- 1 | open Dep 2 | -------------------------------------------------------------------------------- /tests/test-dirs/completion/expansion.t/expansion2.ml: -------------------------------------------------------------------------------- 1 | let x = Lsi.m 2 | -------------------------------------------------------------------------------- /tests/test-dirs/config/workdir.t/src/main.ml: -------------------------------------------------------------------------------- 1 | print_string "foobar" 2 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/module-aliases.t/dune-project: -------------------------------------------------------------------------------- 1 | (lang dune 2.0) 2 | -------------------------------------------------------------------------------- /tests/test-dirs/server-tests/typer-cache/load_path.t/test.ml: -------------------------------------------------------------------------------- 1 | open Dep 2 | -------------------------------------------------------------------------------- /src/frontend/ocamlmerlin/old/old_merlin.mli: -------------------------------------------------------------------------------- 1 | val run : string list -> 'a 2 | -------------------------------------------------------------------------------- /tests/test-dirs/document/src-documentation.t/dune-project: -------------------------------------------------------------------------------- 1 | (lang dune 1.0) 2 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/in-generated-file.t/dune-project: -------------------------------------------------------------------------------- 1 | (lang dune 2.0) 2 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/module-aliases.t/dune: -------------------------------------------------------------------------------- 1 | (executable 2 | (name main)) 3 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/non-local/ignore-kept-locs.t/a.ml: -------------------------------------------------------------------------------- 1 | let value = 3 2 | -------------------------------------------------------------------------------- /upstream/ocaml_413/base-rev.txt: -------------------------------------------------------------------------------- 1 | ab626576eee205615a9d7c5a66c2cb2478f1169c 2 | -------------------------------------------------------------------------------- /upstream/ocaml_414/base-rev.txt: -------------------------------------------------------------------------------- 1 | bfb4b1e608f0d603b189f90a22c06446467c7617 2 | -------------------------------------------------------------------------------- /tests/test-dirs/document/src-documentation.t/dune: -------------------------------------------------------------------------------- 1 | (executable 2 | (name doc)) 3 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/looping-substitution.t/foo.ml: -------------------------------------------------------------------------------- 1 | module Test = Foo_test 2 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/non-local/preference.t/b.mli: -------------------------------------------------------------------------------- 1 | (* deliberately empty *) 2 | -------------------------------------------------------------------------------- /tests/test-dirs/locate-type.t/b.ml: -------------------------------------------------------------------------------- 1 | type foo = string option 2 | let x : foo = None 3 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /src/kernel/mppx.mli: -------------------------------------------------------------------------------- 1 | val rewrite : Mconfig.t -> Mreader.parsetree -> Mreader.parsetree 2 | -------------------------------------------------------------------------------- /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/construct/dune: -------------------------------------------------------------------------------- 1 | (cram 2 | (applies_to :whole_subtree) 3 | (alias construct)) 4 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/non-local/preference.t/a.mli: -------------------------------------------------------------------------------- 1 | (* a comment! *) 2 | 3 | val value : int 4 | -------------------------------------------------------------------------------- /tests/test-dirs/short-paths.t/dep.mli: -------------------------------------------------------------------------------- 1 | 2 | module M : sig type t end 3 | 4 | type t = M.t 5 | -------------------------------------------------------------------------------- /tests/test-dirs/type-enclosing/mod-alias.t/alias.ml: -------------------------------------------------------------------------------- 1 | module L = List 2 | 3 | let _ = L.hd [3] 4 | -------------------------------------------------------------------------------- /vim/merlin/ftplugin/ocaml.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 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/issue802.t/mylib__.ml: -------------------------------------------------------------------------------- 1 | module A = Mylib__A 2 | module Error = Mylib__Error 3 | -------------------------------------------------------------------------------- /tests/test-dirs/type-enclosing/issue1116.t/issue1116.ml: -------------------------------------------------------------------------------- 1 | let some_int = 5 2 | let x = "some_int" 3 | -------------------------------------------------------------------------------- /src/ocaml/preprocess/explain/dune: -------------------------------------------------------------------------------- 1 | (executable 2 | (name gen_explain) 3 | (libraries unix menhirSdk)) 4 | -------------------------------------------------------------------------------- /src/ocaml/preprocess/printer/dune: -------------------------------------------------------------------------------- 1 | (executable 2 | (name gen_printer) 3 | (libraries unix menhirSdk)) 4 | -------------------------------------------------------------------------------- /src/ocaml/preprocess/recover/dune: -------------------------------------------------------------------------------- 1 | (executable 2 | (name gen_recover) 3 | (libraries unix menhirSdk)) 4 | -------------------------------------------------------------------------------- /tests/test-dirs/alerts.t/lib.mli: -------------------------------------------------------------------------------- 1 | val sqrt : float -> float 2 | [@@ocaml.deprecated "I am deprecated"] 3 | -------------------------------------------------------------------------------- /tests/test-dirs/destruct/dune: -------------------------------------------------------------------------------- 1 | (cram 2 | (applies_to :whole_subtree) 3 | (alias all-destruct-tests)) 4 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/in-generated-file.t/main.ml: -------------------------------------------------------------------------------- 1 | let () = Printf.printf "Hello, World: %i\n" Client.x 2 | -------------------------------------------------------------------------------- /tests/test-dirs/type-enclosing/let.t/let.ml: -------------------------------------------------------------------------------- 1 | 2 | let def = 6 3 | 4 | let def : float = float_of_int def 5 | -------------------------------------------------------------------------------- /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/config/flags/dune: -------------------------------------------------------------------------------- 1 | (cram 2 | (applies_to invalid) 3 | (enabled_if 4 | (<> %{os_type} Win32))) 5 | -------------------------------------------------------------------------------- /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/issue845.t/local_map.ml: -------------------------------------------------------------------------------- 1 | module Make(X : Map.OrderedType) = struct 2 | include X 3 | end 4 | -------------------------------------------------------------------------------- /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/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/config/check/dune: -------------------------------------------------------------------------------- 1 | (cram 2 | (applies_to check-config) 3 | (enabled_if 4 | (<> %{os_type} Win32))) 5 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/ambiguity/dune: -------------------------------------------------------------------------------- 1 | (cram 2 | (applies_to rebinding) 3 | (enabled_if 4 | (<> %{os_type} Win32))) 5 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/issue949.t/issue949.ml: -------------------------------------------------------------------------------- 1 | module A = struct let (+.) a b = a +. b end 2 | let f x = A.(x +. 1.) 3 | -------------------------------------------------------------------------------- /tests/test-dirs/document/dune: -------------------------------------------------------------------------------- 1 | (cram 2 | (applies_to src-documentation module-doc) 3 | (enabled_if (<> %{architecture} i386))) 4 | -------------------------------------------------------------------------------- /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/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/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/locate/local-definitions/dune: -------------------------------------------------------------------------------- 1 | (cram 2 | (applies_to issue798 issue806) 3 | (enabled_if 4 | (<> %{os_type} Win32))) 5 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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/locate/issue802.t/error.ml: -------------------------------------------------------------------------------- 1 | type t = Constructor 2 | 3 | exception MyError 4 | 5 | type ext = .. 6 | 7 | type ext += C1 8 | -------------------------------------------------------------------------------- /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/non-local/dune: -------------------------------------------------------------------------------- 1 | (cram 2 | (applies_to ignore-kept-locs preference) 3 | (enabled_if 4 | (<> %{os_type} Win32))) 5 | -------------------------------------------------------------------------------- /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/server-tests/dune: -------------------------------------------------------------------------------- 1 | 2 | (cram 3 | (applies_to :whole_subtree) 4 | (alias all-server-tests) 5 | (locks merlin_server)) 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 | -------------------------------------------------------------------------------- /tests/test-dirs/config/dot-merlin-reader/dune: -------------------------------------------------------------------------------- 1 | (cram 2 | (applies_to erroneous-config quoting) 3 | (enabled_if 4 | (<> %{os_type} Win32))) 5 | -------------------------------------------------------------------------------- /tests/test-dirs/deprecation.t/foo.mli: -------------------------------------------------------------------------------- 1 | 2 | val bar : unit -> int 3 | [@@ocaml.deprecated "deprecation message"] 4 | 5 | val baz : unit -> unit 6 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/issue802.t/a.ml: -------------------------------------------------------------------------------- 1 | open Error 2 | 3 | let f () = raise MyError 4 | 5 | let g () = Constructor 6 | 7 | let c : ext = C1 8 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/issue845.t/local_map.mli: -------------------------------------------------------------------------------- 1 | module Make(X : Map.OrderedType) : sig 2 | include Map.OrderedType with type t = X.t 3 | end 4 | -------------------------------------------------------------------------------- /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/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/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/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/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 | -------------------------------------------------------------------------------- /dune-project: -------------------------------------------------------------------------------- 1 | (lang dune 2.9) 2 | (name merlin) 3 | (using menhir 2.0) 4 | 5 | (cram enable) 6 | (formatting disabled) 7 | (implicit_transitive_deps false) 8 | -------------------------------------------------------------------------------- /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/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/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/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/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/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 | -------------------------------------------------------------------------------- /src/analysis/refactor_open.mli: -------------------------------------------------------------------------------- 1 | 2 | val get_rewrites 3 | : mode:[> `Qualify | `Unqualify ] 4 | -> Mtyper.result 5 | -> Lexing.position 6 | -> (string * Location.t) list 7 | -------------------------------------------------------------------------------- /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 (-open Merlin_utils))) 6 | -------------------------------------------------------------------------------- /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/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/config/dune: -------------------------------------------------------------------------------- 1 | (cram 2 | (applies_to path-expansion) 3 | (enabled_if 4 | (<> %{os_type} Win32))) 5 | 6 | (cram 7 | (applies_to symlinks workdir) 8 | (enabled_if false)) 9 | -------------------------------------------------------------------------------- /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/locate-type.t/a.ml: -------------------------------------------------------------------------------- 1 | module T = struct 2 | type t = X of int 3 | end 4 | 5 | module Y = struct 6 | let y = T.X 1 7 | end 8 | 9 | let z = Y.y 10 | 11 | let z2 = B.x 12 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /src/ocaml/parsing/msupport_parsing.ml: -------------------------------------------------------------------------------- 1 | (* Filled in from Msupport. *) 2 | let msupport_raise_error : (exn -> unit) ref = 3 | ref raise 4 | 5 | let raise_error exn = 6 | !msupport_raise_error exn 7 | -------------------------------------------------------------------------------- /src/ocaml/typing/saved_parts.mli: -------------------------------------------------------------------------------- 1 | val attribute : string Location.loc 2 | val store : Cmt_format.binary_part list -> Parsetree.constant 3 | val find : Parsetree.constant -> Cmt_format.binary_part list 4 | -------------------------------------------------------------------------------- /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/locate/looping-substitution.t/bar.ml: -------------------------------------------------------------------------------- 1 | module Do_the_thing(Test : Foo.Test.S) = struct 2 | let stuff () = () 3 | 4 | include Test 5 | end 6 | 7 | include Do_the_thing(Foo.Test) 8 | -------------------------------------------------------------------------------- /tests/test-dirs/construct/c-modules.t/functor_app.ml: -------------------------------------------------------------------------------- 1 | module type X_int = sig val x : int end 2 | 3 | module Increment (M : X_int) = struct 4 | let x = M.x + 1 5 | end 6 | 7 | module X = Increment(_);; 8 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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/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/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/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/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/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/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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/includes.t/test.ml: -------------------------------------------------------------------------------- 1 | module type S1 = sig 2 | include module type of Foo 3 | 4 | val foo : int t 5 | end 6 | 7 | module type S2 = sig 8 | include module type of struct include Foo end 9 | 10 | val foo : int t 11 | end 12 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /src/extend/dune: -------------------------------------------------------------------------------- 1 | (library 2 | (name merlin_extend) 3 | (public_name merlin-lib.extend) 4 | (modules (:standard \ extend_helper)) 5 | (flags -open Ocaml_utils -open Ocaml_parsing -open Ocaml_typing) 6 | (libraries ocaml_parsing ocaml_typing unix ocaml_utils)) 7 | -------------------------------------------------------------------------------- /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/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/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 -------------------------------------------------------------------------------- /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 | -> keywords : string list 9 | -> values_scope : values_scope 10 | -> Browse_raw.node 11 | -> string list 12 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/issue949.t/run.t: -------------------------------------------------------------------------------- 1 | This test is for testing the behavior of identifiers with a . in them: 2 | 3 | $ $MERLIN single locate -look-for ml -position 2:16 ./issue949.ml < ./issue949.ml 4 | { 5 | "class": "return", 6 | "value": "Not in environment ''", 7 | "notifications": [] 8 | } 9 | -------------------------------------------------------------------------------- /upstream/ocaml_413/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_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 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /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/dune: -------------------------------------------------------------------------------- 1 | (env (_ 2 | (binaries merlin-wrapper) 3 | (env-vars 4 | (MERLIN merlin-wrapper) 5 | (OCAMLC ocamlc)))) 6 | 7 | (cram 8 | (package merlin) 9 | (applies_to :whole_subtree) 10 | (deps 11 | %{bin:merlin-wrapper} 12 | %{bin:ocamlmerlin-server} 13 | %{bin:ocamlmerlin} 14 | %{bin:dot-merlin-reader})) 15 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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) 10 | (libraries merlin_utils ocaml_parsing ocaml_utils)) 11 | -------------------------------------------------------------------------------- /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/dune: -------------------------------------------------------------------------------- 1 | (cram 2 | (applies_to no-escape type-expr environment_on_open locate-type 3 | polarity-search) 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 | -------------------------------------------------------------------------------- /src/frontend/ocamlmerlin/new/new_commands.mli: -------------------------------------------------------------------------------- 1 | open Std 2 | 3 | type command = 4 | Command : string * Marg.docstring * ([`Mandatory|`Optional|`Many] * 'args Marg.spec) list * 'args * 5 | (Mpipeline.t -> 'args -> json) -> command 6 | 7 | val all_commands : command list 8 | 9 | val find_command : string -> command list -> command 10 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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/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 | -------------------------------------------------------------------------------- /src/ocaml/merlin_specific/dune: -------------------------------------------------------------------------------- 1 | (library 2 | (name merlin_specific) 3 | (public_name merlin-lib.ocaml_merlin_specific) 4 | (flags 5 | -open Ocaml_utils 6 | -open Ocaml_parsing 7 | -open Ocaml_preprocess 8 | -open Ocaml_typing 9 | -open Ocaml_preprocess 10 | -open Merlin_utils) 11 | (libraries merlin_utils ocaml_parsing ocaml_preprocess ocaml_typing ocaml_utils)) 12 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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 -> 15 | Reader.request -> 16 | Reader.response 17 | -------------------------------------------------------------------------------- /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": 0 10 | } 11 | }, 12 | "notifications": [] 13 | } 14 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/dune: -------------------------------------------------------------------------------- 1 | (cram 2 | (applies_to looping-substitution mutually-recursive partial-cmt includes 3 | issue802 issue845 issue1199 sig-substs l-413-features module-aliases) 4 | (enabled_if 5 | (<> %{os_type} Win32))) 6 | 7 | (cram 8 | (applies_to issue1424 module-aliases in-generated-file) 9 | (enabled_if 10 | (and 11 | (<> %{architecture} i386) 12 | (<> %{os_type} Win32)))) 13 | -------------------------------------------------------------------------------- /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 asttypes parsetree) 9 | (libraries merlin_utils ocaml_utils)) 10 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /upstream/ocaml_413/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.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 | -------------------------------------------------------------------------------- /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/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": 0 11 | } 12 | }, 13 | "notifications": [] 14 | } 15 | -------------------------------------------------------------------------------- /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/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": "'_weak1", 8 | "labels": [ 9 | { 10 | "name": "~j", 11 | "type": "int" 12 | } 13 | ] 14 | } 15 | ] 16 | -------------------------------------------------------------------------------- /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/type-enclosing/constructors_and_paths.t/cons.ml: -------------------------------------------------------------------------------- 1 | type t = U 2 | type t' = U 3 | 4 | let f : t = U 5 | 6 | let g (x : t) = 7 | match x with 8 | | U -> () 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/misc/external-arity.t: -------------------------------------------------------------------------------- 1 | Bucklescript allow externals to have a non-arrow type. We relax this 2 | restriction in Merlin too as it ease some peoples life and is not really 3 | problematic for normal OCaml users. 4 | 5 | $ $MERLIN single errors -filename external_arity.ml -w +A < external foo : unit list = "foo" 7 | > EOF 8 | { 9 | "class": "return", 10 | "value": [], 11 | "notifications": [] 12 | } 13 | -------------------------------------------------------------------------------- /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 | | sed -e 's:"[^"]*lib/ocaml:"lib/ocaml:g' \ 14 | | sed -e 's:\\n:\ 15 | :g' 16 | -------------------------------------------------------------------------------- /tests/test-dirs/type-enclosing/let.t/run.t: -------------------------------------------------------------------------------- 1 | Get type of a shadowing let binding: 2 | 3 | $ $MERLIN single type-enclosing -position 4:4 -verbosity 0 \ 4 | > -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/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 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /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 | .PHONY: all build dev clean test promote 22 | -------------------------------------------------------------------------------- /tests/test-dirs/outline.t/foo.ml: -------------------------------------------------------------------------------- 1 | module Bar = struct 2 | type t = int 3 | module type S1 = sig 4 | type t 5 | 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 s = s ^ s 16 | end 17 | 18 | exception Ex of char 19 | 20 | type ('a, 'b) eithery = 21 | | Lefty of 'a 22 | | Righty of 'b 23 | 24 | type 'a point = 25 | { x : 'a 26 | ; y : 'a 27 | ; z : 'a 28 | } 29 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 9 | "-o", "" 10 | 11 | let write_lines f s = 12 | let oc = open_out f in 13 | output_string oc s; 14 | close_out oc 15 | 16 | let () = 17 | write_lines pre_flags_f pre_flags; 18 | write_lines post_flags_f post_flags 19 | -------------------------------------------------------------------------------- /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 | 15 | -------------------------------------------------------------------------------- /src/analysis/dune: -------------------------------------------------------------------------------- 1 | (library 2 | (name merlin_analysis) 3 | (public_name merlin-lib.analysis) 4 | (flags 5 | -open Ocaml_utils 6 | -open Ocaml_parsing 7 | -open Ocaml_preprocess 8 | -open Ocaml_typing 9 | -open Merlin_utils 10 | -open Merlin_specific 11 | -open Merlin_extend 12 | -open Merlin_kernel) 13 | (libraries 14 | merlin_config 15 | merlin_specific 16 | merlin_extend 17 | merlin_kernel 18 | merlin_utils 19 | ocaml_parsing 20 | ocaml_preprocess 21 | query_protocol 22 | ocaml_typing 23 | ocaml_utils)) 24 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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 '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 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/looping-substitution.t/run.t: -------------------------------------------------------------------------------- 1 | Setup the test environment: 2 | 3 | $ $OCAMLC -c -bin-annot -o Foo_test test.ml 4 | $ $OCAMLC -c -bin-annot foo.ml 5 | $ $OCAMLC -c -bin-annot bar.ml 6 | 7 | Do the thing: 8 | 9 | $ echo "let () = Bar.the_function ()" | \ 10 | > $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/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 t -> bool 10 | (** Returns true iff the heuristic determines that the file contents has not 11 | changed. *) 12 | 13 | val get: string -> t 14 | (** [file_id filename] computes an id for the current contents of [filename] *) 15 | 16 | val with_cache : (unit -> 'a) -> 'a 17 | -------------------------------------------------------------------------------- /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/issue1109.t/run.t: -------------------------------------------------------------------------------- 1 | FIXME: expected 'a -> 'a 2 | 3 | $ $MERLIN single type-enclosing -position 5:11 -verbosity 0 \ 4 | > -filename ./issue1109.ml < ./issue1109.ml | jq ".value[0:2]" 5 | [ 6 | { 7 | "start": { 8 | "line": 5, 9 | "col": 10 10 | }, 11 | "end": { 12 | "line": 5, 13 | "col": 14 14 | }, 15 | "type": "'a -> 'b", 16 | "tail": "no" 17 | }, 18 | { 19 | "start": { 20 | "line": 5, 21 | "col": 10 22 | }, 23 | "end": { 24 | "line": 5, 25 | "col": 16 26 | }, 27 | "type": "'a", 28 | "tail": "no" 29 | } 30 | ] 31 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /upstream/ocaml_413/parsing/VIPs.md: -------------------------------------------------------------------------------- 1 | # VIPs 2 | 3 | A VIP is a common syntax error, for which a good error message should be 4 | given. 5 | 6 | ## Structures versus signatures 7 | 8 | Everything that is allowed in a structure but forbidden in a signature, 9 | or vice-versa, is a VIP. For instance, writing: 10 | 11 | ``` 12 | exception A = B 13 | ``` 14 | 15 | is allowed in a structure, but forbidden in a signature. (Here, we might 16 | wish to make the error message depend on the lookahead token; the token 17 | `=` suggests that the user confuses a structure and a signature.) 18 | 19 | Similarly, writing `struct` where `sig` is expected, or vice-versa, is 20 | probably a common mistake. 21 | -------------------------------------------------------------------------------- /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 | build: [ 10 | ["dune" "subst"] {dev} 11 | ["dune" "build" "-p" name "-j" jobs] 12 | ] 13 | depends: [ 14 | "ocaml" {>= "4.08" } 15 | "dune" {>= "2.9.0"} 16 | "merlin-lib" {= version} 17 | "ocamlfind" {>= "1.6.0"} 18 | ] 19 | description: 20 | "Helper process: reads .merlin files and outputs the normalized content to 21 | stdout." 22 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/context-detection/cd-label.t/run.t: -------------------------------------------------------------------------------- 1 | 2 | $ $MERLIN single locate -look-for ml -position 4:11 -filename ./label.ml < ./label.ml 3 | { 4 | "class": "return", 5 | "value": { 6 | "file": "$TESTCASE_ROOT/label.ml", 7 | "pos": { 8 | "line": 3, 9 | "col": 4 10 | } 11 | }, 12 | "notifications": [] 13 | } 14 | 15 | $ $MERLIN single locate -look-for ml -position 9:11 -filename ./label.ml < ./label.ml 16 | { 17 | "class": "return", 18 | "value": { 19 | "file": "$TESTCASE_ROOT/label.ml", 20 | "pos": { 21 | "line": 8, 22 | "col": 4 23 | } 24 | }, 25 | "notifications": [] 26 | } 27 | 28 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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 :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_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 | -------------------------------------------------------------------------------- /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/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 | -open Ocaml_utils 9 | -open Merlin_utils 10 | -open Ocaml_parsing 11 | -open Ocaml_preprocess 12 | -open Ocaml_typing 13 | -open Merlin_specific 14 | -open Merlin_extend) 15 | (libraries merlin_config os_ipc ocaml_parsing ocaml_preprocess ocaml_typing ocaml_utils 16 | merlin_extend merlin_specific merlin_utils merlin_dot_protocol)) 17 | 18 | (rule 19 | (targets standard_library.ml) 20 | (action 21 | (write-file %{targets} "let path = {|%{ocaml-config:standard_library}|}"))) 22 | -------------------------------------------------------------------------------- /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 -> t -> 9 | ([`No_labels of bool ] * 10 | [`Implementation of Parsetree.structure | `Interface of Parsetree.signature]) 11 | option 12 | 13 | val reconstruct_identifier : 14 | Lexing.position -> t -> string Location.loc list option 15 | 16 | val print_pretty : 17 | Extend_protocol.Reader.pretty_parsetree -> t -> string option 18 | 19 | val print_outcomes : 20 | Extend_protocol.Reader.outcometree list -> t -> string list option 21 | 22 | val print_outcome : 23 | Extend_protocol.Reader.outcometree -> t -> string option 24 | -------------------------------------------------------------------------------- /tests/test-dirs/errors/issue1222.t: -------------------------------------------------------------------------------- 1 | $ $MERLIN single errors -filename issue1222.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/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 | -------------------------------------------------------------------------------- /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", _ -> 6 | "`OCaml_4_02_3" 7 | | "4", "07", p -> 8 | Printf.sprintf "`OCaml_4_07_%d" p 9 | | maj, min, _ -> 10 | Printf.sprintf "`OCaml_%s_%s_0" maj min 11 | 12 | let () = 13 | Printf.printf {| 14 | let version = "%%VERSION%%" 15 | let ocamlversion : 16 | [ `OCaml_4_02_0 | `OCaml_4_02_1 | `OCaml_4_02_2 | `OCaml_4_02_3 17 | | `OCaml_4_03_0 | `OCaml_4_04_0 | `OCaml_4_05_0 | `OCaml_4_06_0 18 | | `OCaml_4_07_0 | `OCaml_4_07_1 | `OCaml_4_08_0 | `OCaml_4_09_0 19 | | `OCaml_4_10_0 | `OCaml_4_11_0 | `OCaml_4_12_0 | `OCaml_4_13_0 20 | | `OCaml_4_14_0 ] = %s 21 | |} ocaml_version_val 22 | -------------------------------------------------------------------------------- /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": 2 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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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/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/motion/jump.t: -------------------------------------------------------------------------------- 1 | $ $MERLIN single jump -target let -position 2:2 -filename test.ml < let x = 3 | > 5 4 | > EOF 5 | { 6 | "class": "return", 7 | "value": { 8 | "pos": { 9 | "line": 1, 10 | "col": 0 11 | } 12 | }, 13 | "notifications": [] 14 | } 15 | 16 | Same line should fail: 17 | 18 | $ $MERLIN single jump -target let -position 1:8 -filename test.ml < let x = 5 20 | > EOF 21 | { 22 | "class": "return", 23 | "value": "No matching target", 24 | "notifications": [] 25 | } 26 | 27 | $ $MERLIN single jump -target module -position 2:2 -filename test.ml < let x = 29 | > 5 30 | > EOF 31 | { 32 | "class": "return", 33 | "value": "No matching target", 34 | "notifications": [] 35 | } 36 | 37 | -------------------------------------------------------------------------------- /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) -> 'a 19 | 20 | (* Clear caches, remove all items *) 21 | val clear_caches : unit -> unit 22 | 23 | (* Flush caches, remove outdated items *) 24 | val flush_caches : ?older_than:float -> unit -> unit 25 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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": 0 26 | } 27 | }, 28 | "notifications": [] 29 | } 30 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | build: [ 9 | ["dune" "subst"] {dev} 10 | ["dune" "build" "-p" name "-j" jobs] 11 | ] 12 | depends: [ 13 | "ocaml" {>= "4.14" & < "4.15"} 14 | "dune" {>= "2.9.0"} 15 | "csexp" {>= "1.5.1"} 16 | "menhir" {dev} 17 | "menhirLib" {dev} 18 | "menhirSdk" {dev} 19 | ] 20 | synopsis: 21 | "Merlin's libraries" 22 | description: 23 | "These libraries provides access to low-level compiler interfaces and the 24 | standard higher-level merlin protocol. The library is provided as-is, is not 25 | thoroughly documented, and its public API might break with any new release." 26 | -------------------------------------------------------------------------------- /src/frontend/dune: -------------------------------------------------------------------------------- 1 | (library 2 | (name query_protocol) 3 | (public_name merlin-lib.query_protocol) 4 | (modules query_protocol) 5 | (flags -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 | -open Ocaml_utils 14 | -open Ocaml_parsing 15 | -open Ocaml_typing 16 | -open Merlin_kernel 17 | -open Merlin_specific 18 | -open Merlin_utils 19 | -open Merlin_specific 20 | -open Merlin_analysis 21 | -open Merlin_kernel) 22 | (libraries 23 | merlin_utils 24 | merlin_kernel 25 | ocaml_utils 26 | ocaml_parsing 27 | ocaml_typing 28 | merlin_specific 29 | merlin_config 30 | merlin_analysis 31 | query_protocol)) 32 | -------------------------------------------------------------------------------- /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/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/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/occurrences/pattern.t: -------------------------------------------------------------------------------- 1 | This test demonstrates the handling of location of patterns. For a pattern like 2 | (x), the occurrence location should reflect only the identifier. 3 | 4 | $ cat >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 | }, 24 | { 25 | "start": { 26 | "line": 3, 27 | "col": 18 28 | }, 29 | "end": { 30 | "line": 3, 31 | "col": 21 32 | } 33 | } 34 | ], 35 | "notifications": [] 36 | } 37 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/issue1199.t: -------------------------------------------------------------------------------- 1 | When going to the definition of a module defined by a functor, merlin jumps 2 | straight to the functor. 3 | 4 | $ cat > 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": 0 34 | } 35 | }, 36 | "notifications": [] 37 | } 38 | -------------------------------------------------------------------------------- /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": 2 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": 2 27 | } 28 | }, 29 | "notifications": [] 30 | } 31 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /.github/workflows/emacs-lint.yml: -------------------------------------------------------------------------------- 1 | name: Emacs lint 2 | 3 | on: 4 | push: 5 | paths: 6 | - 'emacs/**' 7 | pull_request: 8 | paths: 9 | - 'emacs/**' 10 | 11 | jobs: 12 | build: 13 | runs-on: ubuntu-latest 14 | strategy: 15 | matrix: 16 | emacs_version: 17 | #- 25.1 18 | #- 25.2 19 | #- 25.3 20 | #- 26.1 21 | #- 26.2 22 | #- 26.3 23 | #- 27.1 24 | - 27.2 25 | - snapshot 26 | # include: 27 | # - emacs_version: 24.1 28 | # lint_ignore: 1 29 | # - emacs_version: 24.2 30 | # lint_ignore: 1 31 | env: 32 | EMACS_LINT_IGNORE: ${{ matrix.lint_ignore }} 33 | steps: 34 | - uses: purcell/setup-emacs@master 35 | with: 36 | version: ${{ matrix.emacs_version }} 37 | 38 | - uses: actions/checkout@v2 39 | - name: Run tests 40 | run: 'cd emacs && ./check.sh' 41 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /tests/test-dirs/locate-type.t/run.t: -------------------------------------------------------------------------------- 1 | $ $OCAMLC b.ml -bin-annot -c 2 | 3 | $ $MERLIN single locate-type -position 6:6 -filename ./a.ml < ./a.ml 4 | { 5 | "class": "return", 6 | "value": { 7 | "file": "$TESTCASE_ROOT/a.ml", 8 | "pos": { 9 | "line": 2, 10 | "col": 2 11 | } 12 | }, 13 | "notifications": [] 14 | } 15 | 16 | $ $MERLIN single locate-type -workdir . -position 9:11 -filename a.ml < ./a.ml 17 | { 18 | "class": "return", 19 | "value": { 20 | "file": "$TESTCASE_ROOT/a.ml", 21 | "pos": { 22 | "line": 2, 23 | "col": 2 24 | } 25 | }, 26 | "notifications": [] 27 | } 28 | 29 | $ $MERLIN single locate-type -position 11:12 -filename ./a.ml < ./a.ml 30 | { 31 | "class": "return", 32 | "value": { 33 | "file": "$TESTCASE_ROOT/b.ml", 34 | "pos": { 35 | "line": 1, 36 | "col": 0 37 | } 38 | }, 39 | "notifications": [] 40 | } 41 | -------------------------------------------------------------------------------- /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/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 | $ dune build 22 | 23 | Jump to interface: 24 | $ $MERLIN single locate -look-for mli -position 1:16 \ 25 | > -filename test.ml -filename test.ml t 10 | 11 | (** {1 Position management} *) 12 | 13 | type position = [ 14 | | `Start 15 | | `Offset of int 16 | | `Logical of int * int 17 | | `End 18 | ] 19 | 20 | val get_offset : t -> [< position] -> [> `Offset of int] 21 | 22 | val get_logical : t -> [< position] -> [> `Logical of int * int] 23 | 24 | val get_lexing_pos : t -> filename:string -> [< position] -> Lexing.position 25 | 26 | (** {1 Managing content} *) 27 | 28 | (** Updating content *) 29 | val substitute : t -> [< position] -> [< position | `Length of int] -> string -> t 30 | 31 | (** Source code of the file *) 32 | val text : t -> string 33 | 34 | val dump : t -> Std.json 35 | 36 | val print_position : unit -> [< position] -> string 37 | -------------------------------------------------------------------------------- /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": 0 35 | } 36 | }, 37 | "notifications": [] 38 | } 39 | -------------------------------------------------------------------------------- /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/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\", line 6, characters 9-54: Actual declaration" 27 | } 28 | ], 29 | "notifications": [] 30 | } 31 | 32 | FIXME (appears undeterministic) 33 | $ $MERLIN single errors -filename nasty.ml < nasty.ml 34 | -------------------------------------------------------------------------------- /src/analysis/namespaced_path.mli: -------------------------------------------------------------------------------- 1 | module Namespace : sig 2 | type t = [ 3 | | `Vals 4 | | `Type 5 | | `Constr 6 | | `Mod 7 | | `Modtype 8 | | `Functor 9 | | `Labels 10 | | `Unknown 11 | | `Apply 12 | ] 13 | 14 | val to_string : t -> string 15 | end 16 | 17 | module Id : sig 18 | type t = private 19 | | Id of Ident.t 20 | | String of string 21 | 22 | val name : t -> string 23 | end 24 | 25 | type t (* = private elt list *) 26 | and elt = private 27 | | Ident of Id.t * Namespace.t 28 | | Applied_to of t 29 | 30 | val to_string : t -> string 31 | val to_unique_string : t -> string 32 | 33 | val head : t -> elt option 34 | val head_exn : t -> elt 35 | 36 | val peal_head : t -> t option 37 | val peal_head_exn : t -> t 38 | 39 | val equal : t -> t -> bool 40 | 41 | val rewrite_head : new_prefix:t -> t -> t 42 | 43 | val strip_stamps : t -> t 44 | 45 | val of_path : namespace:Namespace.t -> Path.t -> t 46 | 47 | val empty : t 48 | 49 | val subst_prefix : old_prefix:t -> new_prefix:t -> t -> t option 50 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /tests/test-dirs/document/unattached-comment.t: -------------------------------------------------------------------------------- 1 | A test showing that we manage to get docstrings even when they are not kept as 2 | attributes on the AST. 3 | 4 | $ cat >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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /tests/test-dirs/occurrences/issue1410.t: -------------------------------------------------------------------------------- 1 | FIXME 2 | 3 | First result is incorrect when in the body of a function with an optional argument 4 | 5 | $ $MERLIN single occurrences -identifier-at 3:3 -filename opt.ml < jq '.value' 7 | > (* test case *) 8 | > let f ?(x=1) () = 2 ;; 9 | > None 10 | > EOF 11 | [ 12 | { 13 | "start": { 14 | "line": 0, 15 | "col": -1 16 | }, 17 | "end": { 18 | "line": 0, 19 | "col": -1 20 | } 21 | }, 22 | { 23 | "start": { 24 | "line": 3, 25 | "col": 0 26 | }, 27 | "end": { 28 | "line": 3, 29 | "col": 4 30 | } 31 | } 32 | ] 33 | 34 | $ $MERLIN single occurrences -identifier-at 3:3 -filename opt.ml < jq '.value' 36 | > (* test case *) 37 | > let f () = 2 ;; 38 | > None 39 | > EOF 40 | [ 41 | { 42 | "start": { 43 | "line": 3, 44 | "col": 0 45 | }, 46 | "end": { 47 | "line": 3, 48 | "col": 4 49 | } 50 | } 51 | ] 52 | -------------------------------------------------------------------------------- /tests/test-dirs/construct/c-modules.t/module.ml: -------------------------------------------------------------------------------- 1 | module type S = sig 2 | type t = private b and b = A | B of t 3 | type (-'a, +'b) t' = T of ('a -> '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/locate/includes.t/run.t: -------------------------------------------------------------------------------- 1 | We include another unit, compiled with -no-keep-locs, so there are no locations 2 | in the environment to fallback to: 3 | 4 | $ $OCAMLC -c -bin-annot -no-keep-locs foo.ml 5 | 6 | Test when the include is a name, this should directly redirect us to the right 7 | thing. 8 | 9 | $ $MERLIN single locate -look-for mli -position 4:17 -filename test.ml < test.ml 10 | { 11 | "class": "return", 12 | "value": { 13 | "file": "$TESTCASE_ROOT/foo.ml", 14 | "pos": { 15 | "line": 1, 16 | "col": 0 17 | } 18 | }, 19 | "notifications": [] 20 | } 21 | 22 | Test including a structure: there we will want to look up the ident again inside 23 | the structure, but the stamp will have changed: 24 | 25 | $ $MERLIN single locate -look-for mli -position 10:17 -filename test.ml < test.ml 26 | { 27 | "class": "return", 28 | "value": { 29 | "file": "$TESTCASE_ROOT/foo.ml", 30 | "pos": { 31 | "line": 1, 32 | "col": 0 33 | } 34 | }, 35 | "notifications": [] 36 | } 37 | 38 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /src/utils/file_id.ml: -------------------------------------------------------------------------------- 1 | type t = Unix.stats 2 | 3 | let null_stat = 4 | { Unix. 5 | st_dev = -1; st_ino = -1; st_kind = Unix.S_REG; st_nlink = -1; 6 | st_perm = -1; st_uid = -1; st_gid = -1; st_rdev = -1; st_size = -1; 7 | st_atime = nan; st_mtime = nan; st_ctime = nan } 8 | 9 | let get filename = 10 | try Unix.stat filename 11 | with _ -> null_stat 12 | 13 | let check a b = 14 | a == b || ( 15 | (a != null_stat) && (b != null_stat) && 16 | let open Unix in 17 | a.st_mtime = b.st_mtime && 18 | a.st_size = b.st_size && 19 | a.st_ino = b.st_ino && 20 | a.st_dev = b.st_dev 21 | ) 22 | 23 | let cache = ref None 24 | 25 | let with_cache k = 26 | Std.let_ref cache (Some (Hashtbl.create 7)) k 27 | 28 | let get filename = 29 | match !cache with 30 | | None -> get filename 31 | | Some table -> 32 | match Hashtbl.find table filename with 33 | | stats -> 34 | Logger.log ~section:"stat_cache" ~title:"reuse cache" "%s" filename; 35 | stats 36 | | exception Not_found -> 37 | let stats = get filename in 38 | Hashtbl.add table filename stats; 39 | stats 40 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /src/platform/os_ipc.ml: -------------------------------------------------------------------------------- 1 | type server 2 | type context 3 | 4 | type client = { 5 | context : context; 6 | wd : string; 7 | environ : string; 8 | argv : string array; 9 | } 10 | 11 | (* {1 Server management} 12 | Listen, accept client and close *) 13 | 14 | external server_setup : string -> string -> server option = 15 | "ml_merlin_server_setup" 16 | 17 | external server_accept : server -> timeout:float -> client option = 18 | "ml_merlin_server_accept" 19 | 20 | external server_close : server -> unit = 21 | "ml_merlin_server_close" 22 | 23 | (* {1 Context management (stdin, stdout, stderr)} 24 | Setup and close *) 25 | 26 | external context_setup : context -> unit = 27 | "ml_merlin_context_setup" 28 | 29 | external context_close : context -> return_code:int -> unit = 30 | "ml_merlin_context_close" 31 | 32 | (* {1 Environment management} *) 33 | 34 | external merlin_set_environ : string -> unit = 35 | "ml_merlin_set_environ" 36 | (** completely replace the environment *) 37 | 38 | (* {1 Fixup for Windows process management} *) 39 | 40 | external merlin_dont_inherit_stdio : bool -> unit = "ml_merlin_dont_inherit_stdio" 41 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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": 2 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": 2 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/frontend/ocamlmerlin/dune: -------------------------------------------------------------------------------- 1 | (include_subdirs unqualified) 2 | 3 | (executable 4 | (name ocamlmerlin_server) 5 | (package merlin) 6 | (public_name ocamlmerlin-server) 7 | (flags 8 | -open Ocaml_utils 9 | -open Ocaml_parsing 10 | -open Ocaml_typing 11 | -open Merlin_kernel 12 | -open Merlin_utils 13 | -open Merlin_analysis 14 | -open Merlin_kernel) 15 | (modules (:standard \ gen_ccflags)) 16 | (libraries merlin-lib.config yojson merlin-lib.analysis merlin-lib.kernel 17 | merlin-lib.utils merlin-lib.os_ipc merlin-lib.ocaml_parsing 18 | merlin-lib.query_protocol merlin-lib.query_commands 19 | merlin-lib.ocaml_typing merlin-lib.ocaml_utils)) 20 | 21 | (executable 22 | (name gen_ccflags) 23 | (modules gen_ccflags) 24 | (libraries str)) 25 | 26 | (rule 27 | (targets pre-flags post-flags) 28 | (deps gen_ccflags.exe) 29 | (action (run %{deps} "%{ocaml-config:ccomp_type}" %{targets}))) 30 | 31 | (rule 32 | (targets ocamlmerlin.exe) 33 | (deps (:c ocamlmerlin.c) pre-flags post-flags) 34 | (action (run %{cc} "%{read-lines:pre-flags}%{targets}" %{c} %{read-lines:post-flags}))) 35 | 36 | (install 37 | (package merlin) 38 | (section bin) 39 | (files (ocamlmerlin.exe as ocamlmerlin))) 40 | -------------------------------------------------------------------------------- /src/ocaml/typing/includemod_errorprinter.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* OCaml *) 4 | (* *) 5 | (* Florian Angeletti, projet Cambium, Inria Paris *) 6 | (* *) 7 | (* Copyright 2021 Institut National de Recherche en Informatique et *) 8 | (* en Automatique. *) 9 | (* *) 10 | (* All rights reserved. This file is distributed under the terms of *) 11 | (* the GNU Lesser General Public License version 2.1, with the *) 12 | (* special exception on linking described in the file LICENSE. *) 13 | (* *) 14 | (**************************************************************************) 15 | 16 | val err_msgs: Includemod.explanation -> Format.formatter -> unit 17 | val register: unit -> unit 18 | -------------------------------------------------------------------------------- /src/ocaml/typing/rec_check.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* OCaml *) 4 | (* *) 5 | (* Jeremy Yallop, University of Cambridge *) 6 | (* *) 7 | (* Copyright 2017 Jeremy Yallop *) 8 | (* *) 9 | (* All rights reserved. This file is distributed under the terms of *) 10 | (* the GNU Lesser General Public License version 2.1, with the *) 11 | (* special exception on linking described in the file LICENSE. *) 12 | (* *) 13 | (**************************************************************************) 14 | 15 | exception Illegal_expr 16 | 17 | val is_valid_recursive_expression : Ident.t list -> Typedtree.expression -> bool 18 | 19 | val is_valid_class_expr : Ident.t list -> Typedtree.class_expr -> bool 20 | -------------------------------------------------------------------------------- /upstream/ocaml_413/typing/includemod_errorprinter.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* OCaml *) 4 | (* *) 5 | (* Florian Angeletti, projet Cambium, Inria Paris *) 6 | (* *) 7 | (* Copyright 2021 Institut National de Recherche en Informatique et *) 8 | (* en Automatique. *) 9 | (* *) 10 | (* All rights reserved. This file is distributed under the terms of *) 11 | (* the GNU Lesser General Public License version 2.1, with the *) 12 | (* special exception on linking described in the file LICENSE. *) 13 | (* *) 14 | (**************************************************************************) 15 | 16 | val err_msgs: Includemod.explanation -> Format.formatter -> unit 17 | val register: unit -> unit 18 | -------------------------------------------------------------------------------- /upstream/ocaml_414/typing/includemod_errorprinter.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* OCaml *) 4 | (* *) 5 | (* Florian Angeletti, projet Cambium, Inria Paris *) 6 | (* *) 7 | (* Copyright 2021 Institut National de Recherche en Informatique et *) 8 | (* en Automatique. *) 9 | (* *) 10 | (* All rights reserved. This file is distributed under the terms of *) 11 | (* the GNU Lesser General Public License version 2.1, with the *) 12 | (* special exception on linking described in the file LICENSE. *) 13 | (* *) 14 | (**************************************************************************) 15 | 16 | val err_msgs: Includemod.explanation -> Format.formatter -> unit 17 | val register: unit -> unit 18 | -------------------------------------------------------------------------------- /upstream/ocaml_413/typing/rec_check.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* OCaml *) 4 | (* *) 5 | (* Jeremy Yallop, University of Cambridge *) 6 | (* *) 7 | (* Copyright 2017 Jeremy Yallop *) 8 | (* *) 9 | (* All rights reserved. This file is distributed under the terms of *) 10 | (* the GNU Lesser General Public License version 2.1, with the *) 11 | (* special exception on linking described in the file LICENSE. *) 12 | (* *) 13 | (**************************************************************************) 14 | 15 | exception Illegal_expr 16 | 17 | val is_valid_recursive_expression : Ident.t list -> Typedtree.expression -> bool 18 | 19 | val is_valid_class_expr : Ident.t list -> Typedtree.class_expr -> bool 20 | -------------------------------------------------------------------------------- /upstream/ocaml_414/typing/rec_check.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* OCaml *) 4 | (* *) 5 | (* Jeremy Yallop, University of Cambridge *) 6 | (* *) 7 | (* Copyright 2017 Jeremy Yallop *) 8 | (* *) 9 | (* All rights reserved. This file is distributed under the terms of *) 10 | (* the GNU Lesser General Public License version 2.1, with the *) 11 | (* special exception on linking described in the file LICENSE. *) 12 | (* *) 13 | (**************************************************************************) 14 | 15 | exception Illegal_expr 16 | 17 | val is_valid_recursive_expression : Ident.t list -> Typedtree.expression -> bool 18 | 19 | val is_valid_class_expr : Ident.t list -> Typedtree.class_expr -> bool 20 | -------------------------------------------------------------------------------- /vim/merlin/dune: -------------------------------------------------------------------------------- 1 | (install 2 | (package merlin) 3 | (section share) 4 | (files (autoload/ctrlp/locate.vim as vim/autoload/ctrlp/locate.vim) 5 | (autoload/ctrlp/outline.vim as vim/autoload/ctrlp/outline.vim) 6 | (autoload/neomake/makers/ft/ocaml.vim as vim/autoload/neomake/makers/ft/ocaml.vim) 7 | (autoload/merlin_find.vim as vim/autoload/merlin_find.vim) 8 | (autoload/merlin.py as vim/autoload/merlin.py) 9 | (autoload/merlin_type.vim as vim/autoload/merlin_type.vim) 10 | (autoload/merlin.vim as vim/autoload/merlin.vim) 11 | (autoload/merlin_visual.vim as vim/autoload/merlin_visual.vim) 12 | (doc/merlin.txt as vim/doc/merlin.txt) 13 | (ftdetect/merlin.vim as vim/ftdetect/merlin.vim) 14 | (ftplugin/merlin.vim as vim/ftplugin/merlin.vim) 15 | (ftplugin/ocaml.vim as vim/ftplugin/ocaml.vim) 16 | (ftplugin/omlet.vim as vim/ftplugin/omlet.vim) 17 | (ftplugin/reason.vim as vim/ftplugin/reason.vim) 18 | (plugin/merlin.vim as vim/plugin/merlin.vim) 19 | (syntax_checkers/ocaml/merlin.vim as vim/syntax_checkers/ocaml/merlin.vim) 20 | (syntax_checkers/omlet/merlin.vim as vim/syntax_checkers/omlet/merlin.vim) 21 | (syntax/merlin.vim as vim/syntax/merlin.vim))) 22 | -------------------------------------------------------------------------------- /tests/test-dirs/type-enclosing/github1003.t/run.t: -------------------------------------------------------------------------------- 1 | $ $MERLIN single type-enclosing -position 5:14 -verbosity 0 \ 2 | > -filename ./issue1003.ml < ./issue1003.ml | jq ".value[0:2]" 3 | [ 4 | { 5 | "start": { 6 | "line": 5, 7 | "col": 8 8 | }, 9 | "end": { 10 | "line": 5, 11 | "col": 16 12 | }, 13 | "type": "int", 14 | "tail": "no" 15 | }, 16 | { 17 | "start": { 18 | "line": 5, 19 | "col": 8 20 | }, 21 | "end": { 22 | "line": 5, 23 | "col": 16 24 | }, 25 | "type": "int", 26 | "tail": "no" 27 | } 28 | ] 29 | 30 | $ $MERLIN single type-enclosing -position 5:11 -verbosity 0 \ 31 | > -filename ./issue1003.ml < ./issue1003.ml | jq ".value[0:2]" 32 | [ 33 | { 34 | "start": { 35 | "line": 5, 36 | "col": 8 37 | }, 38 | "end": { 39 | "line": 5, 40 | "col": 12 41 | }, 42 | "type": "sig val foo : int end", 43 | "tail": "no" 44 | }, 45 | { 46 | "start": { 47 | "line": 5, 48 | "col": 8 49 | }, 50 | "end": { 51 | "line": 5, 52 | "col": 16 53 | }, 54 | "type": "int", 55 | "tail": "no" 56 | } 57 | ] 58 | -------------------------------------------------------------------------------- /tests/test-dirs/construct/holes.t: -------------------------------------------------------------------------------- 1 | $ cat >h1.ml < EOF 3 | 4 | $ $MERLIN single holes -filename h1.ml jq ".value" 6 | [] 7 | 8 | 9 | $ cat >h2.ml < let x : int option = _ 11 | > let g x y = x * y 12 | > let f x y = g _ _ 13 | > module M : sig val f : int -> unit end = _ 14 | > EOF 15 | 16 | $ $MERLIN single holes -filename h2.ml jq ".value" 18 | [ 19 | { 20 | "start": { 21 | "line": 1, 22 | "col": 21 23 | }, 24 | "end": { 25 | "line": 1, 26 | "col": 22 27 | }, 28 | "type": "int option" 29 | }, 30 | { 31 | "start": { 32 | "line": 3, 33 | "col": 14 34 | }, 35 | "end": { 36 | "line": 3, 37 | "col": 15 38 | }, 39 | "type": "int" 40 | }, 41 | { 42 | "start": { 43 | "line": 3, 44 | "col": 16 45 | }, 46 | "end": { 47 | "line": 3, 48 | "col": 17 49 | }, 50 | "type": "int" 51 | }, 52 | { 53 | "start": { 54 | "line": 4, 55 | "col": 41 56 | }, 57 | "end": { 58 | "line": 4, 59 | "col": 42 60 | }, 61 | "type": "sig val f : int -> unit end" 62 | } 63 | ] 64 | -------------------------------------------------------------------------------- /tests/test-dirs/destruct/issue1300.t: -------------------------------------------------------------------------------- 1 | From issue 1300: 2 | https://github.com/ocaml/merlin/issues/1300 3 | $ $MERLIN single case-analysis -start 6:5 -end 6:5 -filename i1300.ml < type t = 5 | > | A of int 6 | > | B of int 7 | > 8 | > let f = function 9 | > | A x (* <<< here *) 10 | > | B -> 0 11 | > EOF 12 | { 13 | "class": "error", 14 | "value": "The node on which destruct was called is ill-typed", 15 | "notifications": [] 16 | } 17 | 18 | $ $MERLIN single case-analysis -start 6:5 -end 6:5 -filename i1300.ml < type t = 20 | > | A of int 21 | > | B of int 22 | > 23 | > let f = function 24 | > | A x (* <<< here *) 25 | > | B x -> 0 26 | > EOF 27 | { 28 | "class": "return", 29 | "value": [ 30 | { 31 | "start": { 32 | "line": 6, 33 | "col": 2 34 | }, 35 | "end": { 36 | "line": 7, 37 | "col": 5 38 | } 39 | }, 40 | "A 0 | B x | A _" 41 | ], 42 | "notifications": [] 43 | } 44 | 45 | Fixed: Another stacktrace when "no nodes" 46 | $ $MERLIN single case-analysis -start 7:25 -end 7:25 -filename i1300.ml < EOF 48 | { 49 | "class": "error", 50 | "value": "Nothing to do", 51 | "notifications": [] 52 | } 53 | -------------------------------------------------------------------------------- /tests/test-dirs/occurrences/occ-types.t: -------------------------------------------------------------------------------- 1 | 2 | $ $MERLIN single occurrences -identifier-at 1:6 -filename type.ml < jq '.value' 4 | > type t 5 | > type b = t 6 | > EOF 7 | [ 8 | { 9 | "start": { 10 | "line": 1, 11 | "col": 5 12 | }, 13 | "end": { 14 | "line": 1, 15 | "col": 6 16 | } 17 | }, 18 | { 19 | "start": { 20 | "line": 2, 21 | "col": 9 22 | }, 23 | "end": { 24 | "line": 2, 25 | "col": 10 26 | } 27 | } 28 | ] 29 | 30 | $ $MERLIN single occurrences -identifier-at 1:19 -filename type.ml < jq '.value' 32 | > let f = fun (type t) (foo : t list) -> let (_ : t) = () in () 33 | > EOF 34 | [ 35 | { 36 | "start": { 37 | "line": 1, 38 | "col": 18 39 | }, 40 | "end": { 41 | "line": 1, 42 | "col": 19 43 | } 44 | }, 45 | { 46 | "start": { 47 | "line": 1, 48 | "col": 28 49 | }, 50 | "end": { 51 | "line": 1, 52 | "col": 29 53 | } 54 | }, 55 | { 56 | "start": { 57 | "line": 1, 58 | "col": 48 59 | }, 60 | "end": { 61 | "line": 1, 62 | "col": 49 63 | } 64 | } 65 | ] 66 | -------------------------------------------------------------------------------- /upstream/ocaml_413/parsing/ast_invariants.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* OCaml *) 4 | (* *) 5 | (* Jeremie Dimino, Jane Street Europe *) 6 | (* *) 7 | (* Copyright 2015 Jane Street Group LLC *) 8 | (* *) 9 | (* All rights reserved. This file is distributed under the terms of *) 10 | (* the GNU Lesser General Public License version 2.1, with the *) 11 | (* special exception on linking described in the file LICENSE. *) 12 | (* *) 13 | (**************************************************************************) 14 | 15 | (** Check AST invariants 16 | 17 | {b Warning:} this module is unstable and part of 18 | {{!Compiler_libs}compiler-libs}. 19 | 20 | *) 21 | 22 | val structure : Parsetree.structure -> unit 23 | val signature : Parsetree.signature -> unit 24 | -------------------------------------------------------------------------------- /upstream/ocaml_414/parsing/ast_invariants.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* OCaml *) 4 | (* *) 5 | (* Jeremie Dimino, Jane Street Europe *) 6 | (* *) 7 | (* Copyright 2015 Jane Street Group LLC *) 8 | (* *) 9 | (* All rights reserved. This file is distributed under the terms of *) 10 | (* the GNU Lesser General Public License version 2.1, with the *) 11 | (* special exception on linking described in the file LICENSE. *) 12 | (* *) 13 | (**************************************************************************) 14 | 15 | (** Check AST invariants 16 | 17 | {b Warning:} this module is unstable and part of 18 | {{!Compiler_libs}compiler-libs}. 19 | 20 | *) 21 | 22 | val structure : Parsetree.structure -> unit 23 | val signature : Parsetree.signature -> unit 24 | -------------------------------------------------------------------------------- /src/kernel/mreader.mli: -------------------------------------------------------------------------------- 1 | type parsetree = [ 2 | | `Interface of Parsetree.signature 3 | | `Implementation of Parsetree.structure 4 | ] 5 | 6 | type comment = (string * Location.t) 7 | 8 | type result = { 9 | lexer_keywords: string list; 10 | lexer_errors : exn list; 11 | parser_errors : exn list; 12 | comments : comment list; 13 | parsetree : parsetree; 14 | no_labels_for_completion : bool; 15 | } 16 | 17 | type pretty_parsetree = Extend_protocol.Reader.pretty_parsetree 18 | type outcometree = Extend_protocol.Reader.outcometree 19 | 20 | (* Ambient reader. 21 | 22 | Some actions need to interact with an external process. 23 | `with_ambient_reader' will setup this process to speed up later calls. 24 | *) 25 | 26 | val with_ambient_reader : Mconfig.t -> Msource.t -> (unit -> 'a) -> 'a 27 | 28 | (* Main functions *) 29 | 30 | val parse : 31 | ?for_completion:Msource.position -> Mconfig.t -> Msource.t * parsetree option -> result 32 | 33 | val print_pretty : 34 | Mconfig.t -> Msource.t -> pretty_parsetree -> string 35 | 36 | val print_outcome : 37 | Mconfig.t -> Msource.t -> outcometree -> string 38 | 39 | val print_batch_outcome : 40 | Mconfig.t -> Msource.t -> outcometree list -> string list 41 | 42 | val reconstruct_identifier: 43 | Mconfig.t -> Msource.t -> Lexing.position -> string Location.loc list 44 | -------------------------------------------------------------------------------- /emacs/merlin-xref.el: -------------------------------------------------------------------------------- 1 | ;; -*- lexical-binding: t -*- 2 | (require 'cl-lib) 3 | (require 'xref) 4 | (require 'merlin) 5 | 6 | ;;;###autoload 7 | (defun merlin-xref-backend () 8 | "Merlin backend for Xref." 9 | 'merlin-xref) 10 | 11 | (defun merlin-xref--line (loc) 12 | (save-excursion 13 | (goto-char loc) 14 | (buffer-substring (line-beginning-position) (line-end-position)))) 15 | 16 | (cl-defmethod xref-backend-references ((_backend (eql merlin-xref)) _symbol) 17 | (mapcar 18 | (lambda (loc) 19 | (let ((pt (merlin-make-point (alist-get 'start loc)))) 20 | (xref-make (merlin-xref--line pt) 21 | (xref-make-buffer-location (current-buffer) pt)))) 22 | (merlin--occurrences))) 23 | 24 | (cl-defmethod xref-backend-definitions ((_backend (eql merlin-xref)) _symbol) 25 | (let* ((loc (merlin-call-locate)) 26 | (file (alist-get 'file loc)) 27 | (pos (alist-get 'pos loc)) 28 | (line (alist-get 'line pos)) 29 | (col (alist-get 'col pos))) 30 | (save-excursion 31 | (find-file file) 32 | (let ((desc (merlin-xref--line (merlin-make-point pos)))) 33 | (list (xref-make desc (xref-make-file-location file line col))))))) 34 | 35 | (cl-defmethod xref-backend-identifier-completion-table ((_backend (eql merlin-xref))) 36 | nil) 37 | 38 | (provide 'merlin-xref) 39 | -------------------------------------------------------------------------------- /src/ocaml/typing/typedecl_unboxed.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* OCaml *) 4 | (* *) 5 | (* Gabriel Scherer, projet Parsifal, INRIA Saclay *) 6 | (* Rodolphe Lepigre, projet Deducteam, INRIA Saclay *) 7 | (* *) 8 | (* Copyright 2018 Institut National de Recherche en Informatique et *) 9 | (* en Automatique. *) 10 | (* *) 11 | (* All rights reserved. This file is distributed under the terms of *) 12 | (* the GNU Lesser General Public License version 2.1, with the *) 13 | (* special exception on linking described in the file LICENSE. *) 14 | (* *) 15 | (**************************************************************************) 16 | 17 | open Types 18 | 19 | (* for typeopt.ml *) 20 | val get_unboxed_type_representation: Env.t -> type_expr -> type_expr option 21 | -------------------------------------------------------------------------------- /upstream/ocaml_414/typing/typedecl_unboxed.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* OCaml *) 4 | (* *) 5 | (* Gabriel Scherer, projet Parsifal, INRIA Saclay *) 6 | (* Rodolphe Lepigre, projet Deducteam, INRIA Saclay *) 7 | (* *) 8 | (* Copyright 2018 Institut National de Recherche en Informatique et *) 9 | (* en Automatique. *) 10 | (* *) 11 | (* All rights reserved. This file is distributed under the terms of *) 12 | (* the GNU Lesser General Public License version 2.1, with the *) 13 | (* special exception on linking described in the file LICENSE. *) 14 | (* *) 15 | (**************************************************************************) 16 | 17 | open Types 18 | 19 | (* for typeopt.ml *) 20 | val get_unboxed_type_representation: Env.t -> type_expr -> type_expr option 21 | -------------------------------------------------------------------------------- /tests/test-dirs/server-tests/typer-cache/stamps.t/run.t: -------------------------------------------------------------------------------- 1 | The server might already be running, we kill it to make sure we start from a 2 | clean slate: 3 | $ $MERLIN server stop-server 4 | 5 | Then we can look at identifier stamps and whether they are being reset between 6 | buffers, and different runs for the same buffer: 7 | 8 | $ echo "let f x = x" | \ 9 | > $MERLIN server dump -what browse -filename test.ml | \ 10 | > sed 's:\\n:\n:g' | grep Tpat_var 11 | Tpat_var \"f/273\" 12 | Tpat_var \"x/275\" 13 | 14 | $ echo "let f x = let () = () in x" | \ 15 | > $MERLIN server dump -what browse -filename test.ml | \ 16 | > sed 's:\\n:\n:g' | grep Tpat_var 17 | Tpat_var \"f/276\" 18 | Tpat_var \"x/278\" 19 | 20 | $ echo "let f x = x" | \ 21 | > $MERLIN server dump -what browse -filename other_test.ml | \ 22 | > sed 's:\\n:\n:g' | grep Tpat_var 23 | Tpat_var \"f/273\" 24 | Tpat_var \"x/275\" 25 | 26 | $ echo "let f x = let () = () in x" | \ 27 | > $MERLIN server dump -what browse -filename test.ml | \ 28 | > sed 's:\\n:\n:g' | grep Tpat_var 29 | Tpat_var \"f/276\" 30 | Tpat_var \"x/278\" 31 | 32 | $ echo "let f x = x" | \ 33 | > $MERLIN server dump -what browse -filename test.ml | \ 34 | > sed 's:\\n:\n:g' | grep Tpat_var 35 | Tpat_var \"f/279\" 36 | Tpat_var \"x/281\" 37 | 38 | $ $MERLIN server stop-server 39 | -------------------------------------------------------------------------------- /tests/test-dirs/type-enclosing/issue1278.t: -------------------------------------------------------------------------------- 1 | $ cat >test.ml < module C = struct end 3 | > 4 | > module M = struct 5 | > type t = C 6 | > end 7 | > 8 | > let (_ : M.t) = C 9 | > EOF 10 | 11 | $ ocamlmerlin single type-enclosing -protocol jquery -verbosity 0 \ 12 | > -filename test.ml -position 7:17 -index 0 < test.ml | jq '.value[0]' 13 | { 14 | "start": { 15 | "line": 7, 16 | "col": 16 17 | }, 18 | "end": { 19 | "line": 7, 20 | "col": 17 21 | }, 22 | "type": "M.t", 23 | "tail": "no" 24 | } 25 | 26 | $ ocamlmerlin single type-enclosing -protocol jquery -verbosity 0 \ 27 | > -filename test.ml -position 7:16 -index 0 < test.ml | jq '.value[0]' 28 | { 29 | "start": { 30 | "line": 7, 31 | "col": 16 32 | }, 33 | "end": { 34 | "line": 7, 35 | "col": 17 36 | }, 37 | "type": "M.t", 38 | "tail": "no" 39 | } 40 | 41 | $ cat >>test.ml << EOF 42 | > 43 | > let (_ : M.t) = C 44 | > EOF 45 | 46 | $ ocamlmerlin single type-enclosing -protocol jquery -verbosity 0 \ 47 | > -filename test.ml -position 9:17 -index 0 < test.ml | jq '.value[0]' 48 | { 49 | "start": { 50 | "line": 9, 51 | "col": 16 52 | }, 53 | "end": { 54 | "line": 9, 55 | "col": 17 56 | }, 57 | "type": "M.t", 58 | "tail": "no" 59 | } 60 | -------------------------------------------------------------------------------- /tests/test-dirs/document/module-doc.t: -------------------------------------------------------------------------------- 1 | $ cat >dune-project < (lang dune 2.0) 3 | > EOF 4 | 5 | $ cat >lib.mli < (****************) 7 | > (* SOME LICENCE *) 8 | > (****************) 9 | > 10 | > (** Documentation of Lib *) 11 | > 12 | > (** Documentation of Lib.a *) 13 | > type a = int 14 | > EOF 15 | 16 | $ cat >lib.ml < type a = int 18 | > EOF 19 | 20 | $ cat >libimpl.ml < (****************) 22 | > (* SOME LICENCE *) 23 | > (****************) 24 | > 25 | > (** Documentation of Libimpl *) 26 | > 27 | > (** Documentation of Libimpl.a *) 28 | > type a = int 29 | > EOF 30 | 31 | $ cat >main.ml < type t = Lib.a 33 | > type u = Libimpl.a 34 | > EOF 35 | 36 | $ cat >dune < (executable (name main)) 38 | > EOF 39 | 40 | $ dune build ./main.exe 41 | 42 | The licence is correctly ignored when looking for the doc of Lib 43 | $ $MERLIN single document -position 1:11 \ 44 | > -filename main.ml -filename main.ml module M = struct 5 | > type r = {i: int} 6 | > end 7 | > open M 8 | > let r = {M.i = 1} 9 | > EOF 10 | { 11 | "class": "return", 12 | "value": [ 13 | { 14 | "start": { 15 | "line": 5, 16 | "col": 9 17 | }, 18 | "end": { 19 | "line": 5, 20 | "col": 12 21 | }, 22 | "content": "i" 23 | } 24 | ], 25 | "notifications": [] 26 | } 27 | 28 | Refactor open for record disambiguation 29 | 30 | $ $MERLIN single refactor-open -action qualify -position 1:6 < open Unix 32 | > let f x = x.tms_stime, x.tms_utime 33 | > EOF 34 | { 35 | "class": "return", 36 | "value": [ 37 | { 38 | "start": { 39 | "line": 2, 40 | "col": 12 41 | }, 42 | "end": { 43 | "line": 2, 44 | "col": 21 45 | }, 46 | "content": "Unix.tms_stime" 47 | }, 48 | { 49 | "start": { 50 | "line": 2, 51 | "col": 25 52 | }, 53 | "end": { 54 | "line": 2, 55 | "col": 34 56 | }, 57 | "content": "Unix.tms_utime" 58 | } 59 | ], 60 | "notifications": [] 61 | } 62 | -------------------------------------------------------------------------------- /tests/test-dirs/completion/parenthesize.t/run.t: -------------------------------------------------------------------------------- 1 | $ $MERLIN single complete-prefix -position 11:15 -prefix MyList. \ 2 | > -filename parenthesize.ml < parenthesize.ml | jq ".value.entries | sort_by(.name)" 3 | [ 4 | { 5 | "name": "(())", 6 | "kind": "Constructor", 7 | "desc": "MyList.u", 8 | "info": "", 9 | "deprecated": false 10 | }, 11 | { 12 | "name": "(::)", 13 | "kind": "Constructor", 14 | "desc": "'a * 'a MyList.t -> 'a MyList.t", 15 | "info": "", 16 | "deprecated": false 17 | }, 18 | { 19 | "name": "([])", 20 | "kind": "Constructor", 21 | "desc": "'a MyList.t", 22 | "info": "", 23 | "deprecated": false 24 | }, 25 | { 26 | "name": "(mod)", 27 | "kind": "Value", 28 | "desc": "MyList.u", 29 | "info": "", 30 | "deprecated": false 31 | }, 32 | { 33 | "name": "random", 34 | "kind": "Value", 35 | "desc": "int", 36 | "info": "", 37 | "deprecated": false 38 | }, 39 | { 40 | "name": "t", 41 | "kind": "Type", 42 | "desc": "type 'a t = (::) of 'a * 'a MyList.t | []", 43 | "info": "", 44 | "deprecated": false 45 | }, 46 | { 47 | "name": "u", 48 | "kind": "Type", 49 | "desc": "type u = ()", 50 | "info": "", 51 | "deprecated": false 52 | } 53 | ] 54 | -------------------------------------------------------------------------------- /src/ocaml/typing/annot.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* OCaml *) 4 | (* *) 5 | (* Damien Doligez, projet Gallium, INRIA Rocquencourt *) 6 | (* *) 7 | (* Copyright 2007 Institut National de Recherche en Informatique et *) 8 | (* en Automatique. *) 9 | (* *) 10 | (* All rights reserved. This file is distributed under the terms of *) 11 | (* the GNU Lesser General Public License version 2.1, with the *) 12 | (* special exception on linking described in the file LICENSE. *) 13 | (* *) 14 | (**************************************************************************) 15 | 16 | (* Data types for annotations (Stypes.ml) *) 17 | 18 | type call = Tail | Stack | Inline;; 19 | 20 | type ident = 21 | | Iref_internal of Location.t (* defining occurrence *) 22 | | Iref_external 23 | | Idef of Location.t (* scope *) 24 | ;; 25 | -------------------------------------------------------------------------------- /src/ocaml/utils/clflags.ml: -------------------------------------------------------------------------------- 1 | (** {0 OCaml compiler compatible command-line parameters} *) 2 | 3 | let include_dirs = ref [] 4 | let fast = ref false 5 | let classic = ref false 6 | let principal = ref false 7 | let real_paths = ref true 8 | let recursive_types = ref false 9 | let strict_sequence = ref false 10 | let applicative_functors = ref true 11 | 12 | let unsafe_string = 13 | ref ( 14 | match Merlin_config.ocamlversion with 15 | | `OCaml_4_02_0 | `OCaml_4_02_1 | `OCaml_4_02_2 | `OCaml_4_02_3 16 | | `OCaml_4_03_0 17 | | `OCaml_4_04_0 18 | | `OCaml_4_05_0 -> true 19 | | _ -> false (* -safe-string became the new default in 4.06 *) 20 | ) 21 | 22 | let nopervasives = ref false 23 | let strict_formats = ref false 24 | let open_modules = ref [] 25 | 26 | let annotations = ref false 27 | let binary_annotations = ref true 28 | let print_types = ref false 29 | let native_code = ref false 30 | let error_size = ref 500 31 | let dont_write_files = ref true 32 | let keep_locs = ref true 33 | let keep_docs = ref false 34 | let transparent_modules = ref true 35 | let for_package = ref None 36 | let debug = ref false 37 | let opaque = ref false 38 | let unboxed_types = ref false 39 | 40 | let locations = ref true 41 | -------------------------------------------------------------------------------- /upstream/ocaml_413/utils/domainstate.mli.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************/ 2 | /* */ 3 | /* OCaml */ 4 | /* */ 5 | /* KC Sivaramakrishnan, Indian Institute of Technology, Madras */ 6 | /* Stephen Dolan, University of Cambridge */ 7 | /* */ 8 | /* Copyright 2019 Indian Institute of Technology, Madras */ 9 | /* Copyright 2019 University of Cambridge */ 10 | /* */ 11 | /* All rights reserved. This file is distributed under the terms of */ 12 | /* the GNU Lesser General Public License version 2.1, with the */ 13 | /* special exception on linking described in the file LICENSE. */ 14 | /* */ 15 | /**************************************************************************/ 16 | 17 | type t = 18 | #define DOMAIN_STATE(type, name) | Domain_##name 19 | #include "domain_state.tbl" 20 | #undef DOMAIN_STATE 21 | 22 | val idx_of_field : t -> int 23 | -------------------------------------------------------------------------------- /upstream/ocaml_414/utils/domainstate.mli.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************/ 2 | /* */ 3 | /* OCaml */ 4 | /* */ 5 | /* KC Sivaramakrishnan, Indian Institute of Technology, Madras */ 6 | /* Stephen Dolan, University of Cambridge */ 7 | /* */ 8 | /* Copyright 2019 Indian Institute of Technology, Madras */ 9 | /* Copyright 2019 University of Cambridge */ 10 | /* */ 11 | /* All rights reserved. This file is distributed under the terms of */ 12 | /* the GNU Lesser General Public License version 2.1, with the */ 13 | /* special exception on linking described in the file LICENSE. */ 14 | /* */ 15 | /**************************************************************************/ 16 | 17 | type t = 18 | #define DOMAIN_STATE(type, name) | Domain_##name 19 | #include "domain_state.tbl" 20 | #undef DOMAIN_STATE 21 | 22 | val idx_of_field : t -> int 23 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/functors/f-from_application.t/run.t: -------------------------------------------------------------------------------- 1 | Jump on the argument passed to the functor: 2 | FIXME: we confuse the module for the constructor and jump to the wrong place 3 | 4 | $ $MERLIN single locate -look-for ml -position 11:18 -filename ./from_application.ml < ./from_application.ml 5 | { 6 | "class": "return", 7 | "value": { 8 | "file": "$TESTCASE_ROOT/from_application.ml", 9 | "pos": { 10 | "line": 5, 11 | "col": 0 12 | } 13 | }, 14 | "notifications": [] 15 | } 16 | 17 | Jump from inside the functor application to inside the functor application: 18 | 19 | $ $MERLIN single locate -look-for ml -position 18:16 -filename ./from_application.ml < ./from_application.ml 20 | { 21 | "class": "return", 22 | "value": { 23 | "file": "$TESTCASE_ROOT/from_application.ml", 24 | "pos": { 25 | "line": 14, 26 | "col": 4 27 | } 28 | }, 29 | "notifications": [] 30 | } 31 | 32 | Jump from inside the functor application to the outer scope: 33 | 34 | $ $MERLIN single locate -look-for ml -position 14:18 -filename ./from_application.ml < ./from_application.ml 35 | { 36 | "class": "return", 37 | "value": { 38 | "file": "$TESTCASE_ROOT/from_application.ml", 39 | "pos": { 40 | "line": 9, 41 | "col": 0 42 | } 43 | }, 44 | "notifications": [] 45 | } 46 | 47 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/issue845.t/run.t: -------------------------------------------------------------------------------- 1 | To properly test this, we need to have the functor in a different file than the 2 | one we jump from, otherwise we will get a location from the environment, which 3 | can be used as a fallback something fails later on. 4 | 5 | And we also do not want to use a functor from the stdlib, because locations, 6 | paths, etc. will change between versions of OCaml, so we define and compile a 7 | module containing a functor locally: 8 | 9 | $ $OCAMLC -c -bin-annot local_map.mli 10 | $ $OCAMLC -c -bin-annot local_map.ml 11 | 12 | Test jumping to impl: 13 | 14 | FIXME: this jumps to the .mli... 15 | 16 | $ $MERLIN single locate -look-for ml -position 1:24 -filename test.ml < module SM = Local_map.Make(String) 18 | > EOF 19 | { 20 | "class": "return", 21 | "value": { 22 | "file": "$TESTCASE_ROOT/local_map.ml", 23 | "pos": { 24 | "line": 1, 25 | "col": 0 26 | } 27 | }, 28 | "notifications": [] 29 | } 30 | 31 | Test jumping to intf: 32 | 33 | $ $MERLIN single locate -look-for mli -position 1:24 -filename test.ml < module SM = Local_map.Make(String) 35 | > EOF 36 | { 37 | "class": "return", 38 | "value": { 39 | "file": "$TESTCASE_ROOT/local_map.mli", 40 | "pos": { 41 | "line": 1, 42 | "col": 0 43 | } 44 | }, 45 | "notifications": [] 46 | } 47 | 48 | -------------------------------------------------------------------------------- /upstream/ocaml_413/typing/annot.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* OCaml *) 4 | (* *) 5 | (* Damien Doligez, projet Gallium, INRIA Rocquencourt *) 6 | (* *) 7 | (* Copyright 2007 Institut National de Recherche en Informatique et *) 8 | (* en Automatique. *) 9 | (* *) 10 | (* All rights reserved. This file is distributed under the terms of *) 11 | (* the GNU Lesser General Public License version 2.1, with the *) 12 | (* special exception on linking described in the file LICENSE. *) 13 | (* *) 14 | (**************************************************************************) 15 | 16 | (* Data types for annotations (Stypes.ml) *) 17 | 18 | type call = Tail | Stack | Inline;; 19 | 20 | type ident = 21 | | Iref_internal of Location.t (* defining occurrence *) 22 | | Iref_external 23 | | Idef of Location.t (* scope *) 24 | ;; 25 | -------------------------------------------------------------------------------- /upstream/ocaml_413/typing/printtyped.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* OCaml *) 4 | (* *) 5 | (* Damien Doligez, projet Para, INRIA Rocquencourt *) 6 | (* *) 7 | (* Copyright 1999 Institut National de Recherche en Informatique et *) 8 | (* en Automatique. *) 9 | (* *) 10 | (* All rights reserved. This file is distributed under the terms of *) 11 | (* the GNU Lesser General Public License version 2.1, with the *) 12 | (* special exception on linking described in the file LICENSE. *) 13 | (* *) 14 | (**************************************************************************) 15 | 16 | open Typedtree;; 17 | open Format;; 18 | 19 | val interface : formatter -> signature -> unit;; 20 | val implementation : formatter -> structure -> unit;; 21 | 22 | val implementation_with_coercion : 23 | formatter -> Typedtree.implementation -> unit;; 24 | -------------------------------------------------------------------------------- /upstream/ocaml_414/typing/annot.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* OCaml *) 4 | (* *) 5 | (* Damien Doligez, projet Gallium, INRIA Rocquencourt *) 6 | (* *) 7 | (* Copyright 2007 Institut National de Recherche en Informatique et *) 8 | (* en Automatique. *) 9 | (* *) 10 | (* All rights reserved. This file is distributed under the terms of *) 11 | (* the GNU Lesser General Public License version 2.1, with the *) 12 | (* special exception on linking described in the file LICENSE. *) 13 | (* *) 14 | (**************************************************************************) 15 | 16 | (* Data types for annotations (Stypes.ml) *) 17 | 18 | type call = Tail | Stack | Inline;; 19 | 20 | type ident = 21 | | Iref_internal of Location.t (* defining occurrence *) 22 | | Iref_external 23 | | Idef of Location.t (* scope *) 24 | ;; 25 | -------------------------------------------------------------------------------- /upstream/ocaml_414/typing/printtyped.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* OCaml *) 4 | (* *) 5 | (* Damien Doligez, projet Para, INRIA Rocquencourt *) 6 | (* *) 7 | (* Copyright 1999 Institut National de Recherche en Informatique et *) 8 | (* en Automatique. *) 9 | (* *) 10 | (* All rights reserved. This file is distributed under the terms of *) 11 | (* the GNU Lesser General Public License version 2.1, with the *) 12 | (* special exception on linking described in the file LICENSE. *) 13 | (* *) 14 | (**************************************************************************) 15 | 16 | open Typedtree;; 17 | open Format;; 18 | 19 | val interface : formatter -> signature -> unit;; 20 | val implementation : formatter -> structure -> unit;; 21 | 22 | val implementation_with_coercion : 23 | formatter -> Typedtree.implementation -> unit;; 24 | -------------------------------------------------------------------------------- /doc/dev/SERVER.md: -------------------------------------------------------------------------------- 1 | Merlin now implements a server. This simplify implementation of editor modes by 2 | allowing synchronous process executions. 3 | 4 | The `ocamlmerlin` binary is a wrapper, written in C, that redirects queries to 5 | `ocamlmerlin-server`. 6 | 7 | It can be used in a few different ways. 8 | 9 | `old-protocol` works as a repl: one writes a query (formatted as a json value) 10 | and reads an answer (also json). It is the protocol of merlin 1.x and 2.x. 11 | When detecting old-protocol, `ocamlmerlin` wrapper simply executes the 12 | ocamlmerlin-server. It is documented in [OLD-PROTOCOL.md](OLD-PROTOCOL.md). 13 | 14 | With the new protocol, the query is specified on the command-line and the 15 | content is read from standard input. Merlin can now be used like a regular 16 | UNIX command. Answers are written on standard output as JSON-values (or 17 | optionally, S-expression). 18 | 19 | In `single` mode, the wrapper executes `ocamlmerlin-server` and processes a 20 | single query. 21 | In `server` mode, the wrapper looks for an existing server. If none are found, 22 | it executes a new one. Then it redirects the query to the server, wait for an 23 | answer and terminates. 24 | 25 | The editor plugin does the same work in both cases, caching & calling the 26 | server is transparent. 27 | 28 | Mode is specified as the first argument to `ocamlmerlin` binary, and defaults to 29 | `old-protocol` for compatibility with previous versions. 30 | -------------------------------------------------------------------------------- /src/kernel/mtyper.mli: -------------------------------------------------------------------------------- 1 | (** {1 Result of typechecker} 2 | 3 | [Mtyper] essentially produces a typedtree, but to make sense of it 4 | the OCaml typechecker need to be in a specific state. 5 | 6 | The [result] type wraps a snapshot of this state with the typedtree to 7 | ensure correct accesses. 8 | *) 9 | 10 | type result 11 | 12 | type typedtree = [ 13 | | `Interface of Typedtree.signature 14 | | `Implementation of Typedtree.structure 15 | ] 16 | 17 | val run : Mconfig.t -> Mreader.parsetree -> result 18 | 19 | val get_env : ?pos:Msource.position -> result -> Env.t 20 | 21 | val get_typedtree : result -> typedtree 22 | 23 | val get_errors : result -> exn list 24 | 25 | (** Heuristic to find suitable environment to complete / type at given position. 26 | * 1. Try to find environment near given cursor. 27 | * 2. Check if there is an invalid construct between found env and cursor : 28 | * Case a. 29 | * > let x = valid_expr || 30 | * The env found is the right most env from valid_expr, it's a correct 31 | * answer. 32 | * Case b. 33 | * > let x = valid_expr 34 | * > let y = invalid_construction|| 35 | * In this case, the env found is the same as in case a, however it is 36 | * preferable to use env from enclosing module rather than an env from 37 | * inside x definition. 38 | *) 39 | val node_at : 40 | ?skip_recovered:bool -> result -> Lexing.position -> Mbrowse.t 41 | -------------------------------------------------------------------------------- /tests/test-dirs/type-enclosing/mod-not-in-env.t/run.t: -------------------------------------------------------------------------------- 1 | $ $MERLIN single type-enclosing -position 5:9 -verbosity 0 \ 2 | > -filename ./not-in-env.ml < ./not-in-env.ml | jq ".value[0:2]" 3 | [ 4 | { 5 | "start": { 6 | "line": 5, 7 | "col": 8 8 | }, 9 | "end": { 10 | "line": 5, 11 | "col": 9 12 | }, 13 | "type": "sig val y : int end", 14 | "tail": "no" 15 | }, 16 | { 17 | "start": { 18 | "line": 5, 19 | "col": 8 20 | }, 21 | "end": { 22 | "line": 5, 23 | "col": 11 24 | }, 25 | "type": "'a", 26 | "tail": "no" 27 | } 28 | ] 29 | 30 | $ $MERLIN single type-enclosing -position 5:11 -verbosity 0 \ 31 | > -filename ./not-in-env.ml < ./not-in-env.ml | jq ".value[0:2]" 32 | [ 33 | { 34 | "start": { 35 | "line": 5, 36 | "col": 8 37 | }, 38 | "end": { 39 | "line": 5, 40 | "col": 11 41 | }, 42 | "type": "'a", 43 | "tail": "no" 44 | } 45 | ] 46 | 47 | $ $MERLIN single type-enclosing -position 7:11 -verbosity 0 \ 48 | > -filename ./not-in-env.ml < ./not-in-env.ml | jq ".value[0:2]" 49 | [ 50 | { 51 | "start": { 52 | "line": 7, 53 | "col": 8 54 | }, 55 | "end": { 56 | "line": 7, 57 | "col": 11 58 | }, 59 | "type": "'a", 60 | "tail": "no" 61 | } 62 | ] 63 | -------------------------------------------------------------------------------- /src/ocaml/preprocess/dune: -------------------------------------------------------------------------------- 1 | (ocamllex lexer_ident lexer_raw) 2 | 3 | (library 4 | (name ocaml_preprocess) 5 | (public_name merlin-lib.ocaml_preprocess) 6 | (flags -open Ocaml_parsing -open Ocaml_utils -open Merlin_utils) 7 | (libraries ocaml_parsing ocaml_utils merlin_utils)) 8 | 9 | (menhir 10 | (modules parser_raw) 11 | (enabled_if (<> %{profile} "release")) 12 | (mode promote) 13 | (flags :standard --inspection --table --cmly)) 14 | 15 | (rule 16 | (targets parser_recover.ml) 17 | (enabled_if (<> %{profile} "release")) 18 | (deps parser_raw.cmly) 19 | (mode promote) 20 | (action 21 | (with-stdout-to %{targets} 22 | (run %{exe:./recover/gen_recover.exe} %{deps})))) 23 | 24 | (rule 25 | (targets parser_explain.ml) 26 | (enabled_if (<> %{profile} "release")) 27 | (deps parser_raw.cmly) 28 | (mode promote) 29 | (action 30 | (with-stdout-to %{targets} 31 | (run %{exe:./explain/gen_explain.exe} %{deps})))) 32 | 33 | (rule 34 | (targets parser_printer.ml) 35 | (enabled_if (<> %{profile} "release")) 36 | (deps parser_raw.cmly) 37 | (mode promote) 38 | (action 39 | (with-stdout-to %{targets} 40 | (run %{exe:./printer/gen_printer.exe} %{deps})))) 41 | 42 | (rule 43 | (targets menhirLib.ml menhirLib.mli) 44 | (mode promote) 45 | (action 46 | (progn 47 | (copy %{lib:menhirLib:menhirLib.ml} menhirLib.ml) 48 | (copy %{lib:menhirLib:menhirLib.mli} menhirLib.mli)))) 49 | -------------------------------------------------------------------------------- /upstream/ocaml_413/typing/typedecl_unboxed.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* OCaml *) 4 | (* *) 5 | (* Gabriel Scherer, projet Parsifal, INRIA Saclay *) 6 | (* Rodolphe Lepigre, projet Deducteam, INRIA Saclay *) 7 | (* *) 8 | (* Copyright 2018 Institut National de Recherche en Informatique et *) 9 | (* en Automatique. *) 10 | (* *) 11 | (* All rights reserved. This file is distributed under the terms of *) 12 | (* the GNU Lesser General Public License version 2.1, with the *) 13 | (* special exception on linking described in the file LICENSE. *) 14 | (* *) 15 | (**************************************************************************) 16 | 17 | open Types 18 | 19 | type t = 20 | | Unavailable 21 | | This of type_expr 22 | | Only_on_64_bits of type_expr 23 | 24 | (* for typeopt.ml *) 25 | val get_unboxed_type_representation: Env.t -> type_expr -> t 26 | -------------------------------------------------------------------------------- /tests/test-dirs/document/src-documentation.t/run.t: -------------------------------------------------------------------------------- 1 | $ cat >a.ml < (** a function *) 3 | > let b () = () 4 | > 5 | > (** A function *) 6 | > let a () = () 7 | > 8 | > (** a function *) 9 | > let c () = () 10 | > EOF 11 | 12 | $ cat >doc.ml < (** first function *) 14 | > let f () = () 15 | > 16 | > (** second function *) 17 | > let g () = () 18 | > 19 | > let () = g (f ()) 20 | > 21 | > let list_rev = List.rev 22 | > 23 | > let () = A.a () 24 | > EOF 25 | 26 | documentation for the last defined value (in the same file) is shown 27 | $ $MERLIN single document -position 7:10 -filename doc.ml < doc.ml | 28 | > jq '.value' 29 | "second function" 30 | 31 | documentation for the non-last defined value (in the same file) is show 32 | (we care about "non-last" value because of issue #1261) 33 | $ $MERLIN single document -position 7:13 -filename doc.ml < doc.ml | 34 | > jq '.value' 35 | "first function" 36 | 37 | $ $MERLIN single document -position 9:6 -filename doc.ml < doc.ml | 38 | > jq '.value' 39 | "No documentation available" 40 | 41 | $ $MERLIN single document -position 9:22 -filename doc.ml < doc.ml | 42 | > jq '.value' 43 | "List reversal." 44 | 45 | $ dune build --root=. ./doc.exe 2> /dev/null 46 | $ cat >.merlin < B _build/default/.doc.eobjs/byte 48 | > S . 49 | > EOF 50 | 51 | $ $MERLIN single document -position 11:12 -filename doc.ml < doc.ml | 52 | > jq '.value' 53 | "A function" 54 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/context-detection/cd-field.t/run.t: -------------------------------------------------------------------------------- 1 | 2 | $ $MERLIN single locate -look-for ml -position 3:14 -filename ./field.ml < ./field.ml 3 | { 4 | "class": "return", 5 | "value": { 6 | "file": "$TESTCASE_ROOT/field.ml", 7 | "pos": { 8 | "line": 1, 9 | "col": 0 10 | } 11 | }, 12 | "notifications": [] 13 | } 14 | 15 | $ $MERLIN single locate -look-for ml -position 7:14 -filename ./field.ml < ./field.ml 16 | { 17 | "class": "return", 18 | "value": { 19 | "file": "$TESTCASE_ROOT/field.ml", 20 | "pos": { 21 | "line": 1, 22 | "col": 0 23 | } 24 | }, 25 | "notifications": [] 26 | } 27 | 28 | Merlin is confused by punned fields prefixed by the module. { X.bar } goes to 29 | the field bar rather than the identifier. 30 | $ $MERLIN single locate -look-for ml -position 15:14 -filename ./field.ml < ./field.ml 31 | { 32 | "class": "return", 33 | "value": { 34 | "file": "$TESTCASE_ROOT/field.ml", 35 | "pos": { 36 | "line": 10, 37 | "col": 2 38 | } 39 | }, 40 | "notifications": [] 41 | } 42 | 43 | Normal punning works as expected: 44 | $ $MERLIN single locate -look-for ml -position 15:19 -filename ./field.ml < ./field.ml 45 | { 46 | "class": "return", 47 | "value": { 48 | "file": "$TESTCASE_ROOT/field.ml", 49 | "pos": { 50 | "line": 14, 51 | "col": 4 52 | } 53 | }, 54 | "notifications": [] 55 | } 56 | -------------------------------------------------------------------------------- /tests/test-dirs/alerts.t/run.t: -------------------------------------------------------------------------------- 1 | $ echo "S .\nB .\nFLG -nopervasives" > .merlin 2 | $ $OCAMLC -nopervasives -c -bin-annot lib.mli 3 | $ $MERLIN single errors -filename main.ml < main.ml 4 | { 5 | "class": "return", 6 | "value": [ 7 | { 8 | "start": { 9 | "line": 2, 10 | "col": 8 11 | }, 12 | "end": { 13 | "line": 2, 14 | "col": 12 15 | }, 16 | "type": "warning", 17 | "sub": [], 18 | "valid": true, 19 | "message": "Alert deprecated: Lib.sqrt 20 | I am deprecated" 21 | } 22 | ], 23 | "notifications": [] 24 | } 25 | 26 | $ cat > .merlin < S . 28 | > B . 29 | > FLG -nopervasives -alert -deprecated 30 | > EOF 31 | 32 | $ $MERLIN single errors -filename main.ml < main.ml 33 | { 34 | "class": "return", 35 | "value": [], 36 | "notifications": [] 37 | } 38 | 39 | $ cat > .merlin < S . 41 | > B . 42 | > FLG -nopervasives -alert=-deprecated 43 | > EOF 44 | 45 | $ $MERLIN single errors -filename main.ml < main.ml 46 | { 47 | "class": "return", 48 | "value": [], 49 | "notifications": [] 50 | } 51 | 52 | The compiler accept both 53 | $ $OCAMLC -c main.ml 54 | File "main.ml", line 2, characters 8-12: 55 | 2 | let x = sqrt 3. 56 | ^^^^ 57 | Alert deprecated: Lib.sqrt 58 | I am deprecated 59 | 60 | $ $OCAMLC -alert -deprecated -c main.ml 61 | 62 | $ $OCAMLC -alert=-deprecated -c main.ml 63 | -------------------------------------------------------------------------------- /upstream/ocaml_413/utils/binutils.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* OCaml *) 4 | (* *) 5 | (* Nicolas Ojeda Bar, LexiFi *) 6 | (* *) 7 | (* Copyright 2020 Institut National de Recherche en Informatique et *) 8 | (* en Automatique. *) 9 | (* *) 10 | (* All rights reserved. This file is distributed under the terms of *) 11 | (* the GNU Lesser General Public License version 2.1, with the *) 12 | (* special exception on linking described in the file LICENSE. *) 13 | (* *) 14 | (**************************************************************************) 15 | 16 | type error = 17 | | Truncated_file 18 | | Unrecognized of string 19 | | Unsupported of string * int64 20 | | Out_of_range of string 21 | 22 | val error_to_string: error -> string 23 | 24 | type t 25 | 26 | val read: string -> (t, error) Result.t 27 | 28 | val defines_symbol: t -> string -> bool 29 | 30 | val symbol_offset: t -> string -> int64 option 31 | -------------------------------------------------------------------------------- /upstream/ocaml_414/utils/binutils.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* OCaml *) 4 | (* *) 5 | (* Nicolas Ojeda Bar, LexiFi *) 6 | (* *) 7 | (* Copyright 2020 Institut National de Recherche en Informatique et *) 8 | (* en Automatique. *) 9 | (* *) 10 | (* All rights reserved. This file is distributed under the terms of *) 11 | (* the GNU Lesser General Public License version 2.1, with the *) 12 | (* special exception on linking described in the file LICENSE. *) 13 | (* *) 14 | (**************************************************************************) 15 | 16 | type error = 17 | | Truncated_file 18 | | Unrecognized of string 19 | | Unsupported of string * int64 20 | | Out_of_range of string 21 | 22 | val error_to_string: error -> string 23 | 24 | type t 25 | 26 | val read: string -> (t, error) Result.t 27 | 28 | val defines_symbol: t -> string -> bool 29 | 30 | val symbol_offset: t -> string -> int64 option 31 | -------------------------------------------------------------------------------- /src/ocaml/typing/printtyped.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* OCaml *) 4 | (* *) 5 | (* Damien Doligez, projet Para, INRIA Rocquencourt *) 6 | (* *) 7 | (* Copyright 1999 Institut National de Recherche en Informatique et *) 8 | (* en Automatique. *) 9 | (* *) 10 | (* All rights reserved. This file is distributed under the terms of *) 11 | (* the GNU Lesser General Public License version 2.1, with the *) 12 | (* special exception on linking described in the file LICENSE. *) 13 | (* *) 14 | (**************************************************************************) 15 | 16 | open Typedtree;; 17 | open Format;; 18 | 19 | val interface : formatter -> signature -> unit;; 20 | val implementation : formatter -> structure -> unit;; 21 | 22 | val implementation_with_coercion : 23 | formatter -> Typedtree.implementation -> unit;; 24 | 25 | (* Added by merlin for debugging purposes *) 26 | val pattern : int -> formatter -> _ general_pattern -> unit 27 | -------------------------------------------------------------------------------- /appveyor.cmd: -------------------------------------------------------------------------------- 1 | @setlocal 2 | @echo off 3 | 4 | set Path=C:\cygwin\bin;%Path% 5 | set OCAML_PREV_PATH=%PATH% 6 | set OCAML_PREV_LIB=%LIB% 7 | set OCAML_PREV_INCLUDE=%INCLUDE% 8 | 9 | bash -lc "$APPVEYOR_BUILD_FOLDER/appveyor.sh prepare mingw" 10 | if errorlevel 1 exit /b 1 11 | bash -lc "$APPVEYOR_BUILD_FOLDER/appveyor.sh prepare mingw64" 12 | if errorlevel 1 exit /b 1 13 | call "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd" /x86 /release 14 | bash -lc "$APPVEYOR_BUILD_FOLDER/appveyor.sh prepare msvc" 15 | if errorlevel 1 exit /b 1 16 | set PATH=%OCAML_PREV_PATH% 17 | set LIB=%OCAML_PREV_LIB% 18 | set INCLUDE=%OCAML_PREV_INCLUDE% 19 | call "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd" /x64 /release 20 | bash -lc "$APPVEYOR_BUILD_FOLDER/appveyor.sh prepare msvc64" 21 | if errorlevel 1 exit /b 1 22 | bash -lc "$APPVEYOR_BUILD_FOLDER/appveyor.sh matrix" 23 | bash -lc "$APPVEYOR_BUILD_FOLDER/appveyor.sh build msvc64" 24 | if errorlevel 1 exit /b 1 25 | set PATH=%OCAML_PREV_PATH% 26 | set LIB=%OCAML_PREV_LIB% 27 | set INCLUDE=%OCAML_PREV_INCLUDE% 28 | call "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd" /x86 /release 29 | bash -lc "$APPVEYOR_BUILD_FOLDER/appveyor.sh build msvc" 30 | if errorlevel 1 exit /b 1 31 | set PATH=%OCAML_PREV_PATH% 32 | set LIB=%OCAML_PREV_LIB% 33 | set INCLUDE=%OCAML_PREV_INCLUDE% 34 | bash -lc "$APPVEYOR_BUILD_FOLDER/appveyor.sh build mingw" 35 | if errorlevel 1 exit /b 1 36 | bash -lc "$APPVEYOR_BUILD_FOLDER/appveyor.sh build mingw64" 37 | if errorlevel 1 exit /b 1 38 | -------------------------------------------------------------------------------- /src/kernel/mreader_recover.mli: -------------------------------------------------------------------------------- 1 | module Make 2 | (Parser : MenhirLib.IncrementalEngine.EVERYTHING) 3 | (Recovery : sig 4 | val default_value : Location.t -> 'a Parser.symbol -> 'a 5 | 6 | type action = 7 | | Abort 8 | | R of int 9 | | S : 'a Parser.symbol -> action 10 | | Sub of action list 11 | 12 | type decision = 13 | | Nothing 14 | | One of action list 15 | | Select of (int -> action list) 16 | 17 | val depth : int array 18 | 19 | val can_pop : 'a Parser.terminal -> bool 20 | 21 | val recover : int -> decision 22 | 23 | val guide : 'a Parser.symbol -> bool 24 | 25 | val token_of_terminal : 'a Parser.terminal -> 'a -> Parser.token 26 | 27 | val nullable : 'a Parser.nonterminal -> bool 28 | end) 29 | (Dump : sig 30 | val symbol : unit -> Parser.xsymbol -> string 31 | end) : 32 | sig 33 | 34 | type 'a candidate = { 35 | line: int; 36 | min_col: int; 37 | max_col: int; 38 | env: 'a Parser.env; 39 | } 40 | 41 | type 'a candidates = { 42 | popped: Parser.xsymbol list; 43 | shifted: Parser.xsymbol option; 44 | final: 'a option; 45 | candidates: 'a candidate list; 46 | } 47 | 48 | val attempt : 'a candidates -> 49 | Parser.token * Lexing.position * Lexing.position -> 50 | [> `Accept of 'a 51 | | `Fail 52 | | `Ok of 'a Parser.checkpoint * 'a Parser.env ] 53 | 54 | val generate : 'a Parser.env -> 'a candidates 55 | 56 | end 57 | -------------------------------------------------------------------------------- /src/ocaml/utils/clflags.mli: -------------------------------------------------------------------------------- 1 | (** {0 OCaml compiler compatible command-line parameters} 2 | 3 | For compatibility with typechecker. 4 | Argument parsing / build environment construction happens elsewhere. 5 | *) 6 | 7 | (** {1 Relevant settings} 8 | Parameters from OCaml compiler which affect Merlin behavior. *) 9 | val include_dirs : string list ref 10 | val fast : bool ref 11 | val classic : bool ref 12 | val principal : bool ref 13 | val real_paths : bool ref 14 | val recursive_types : bool ref 15 | val strict_sequence : bool ref 16 | val applicative_functors : bool ref 17 | val unsafe_string : bool ref 18 | val nopervasives : bool ref 19 | val strict_formats : bool ref 20 | val open_modules : string list ref 21 | 22 | (** {1 Dummy values} 23 | Ignored by merlin but kept for compatibility with upstream code. *) 24 | val annotations : bool ref 25 | val binary_annotations : bool ref 26 | val print_types : bool ref 27 | val native_code : bool ref 28 | val dont_write_files : bool ref 29 | val error_size : int ref (* max size of module related errors *) 30 | val keep_locs : bool ref 31 | val keep_docs : bool ref 32 | val transparent_modules : bool ref 33 | val for_package : string option ref 34 | val debug : bool ref 35 | val opaque : bool ref 36 | val unboxed_types : bool ref 37 | 38 | val locations : bool ref 39 | -------------------------------------------------------------------------------- /src/ocaml/preprocess/lexer_ident.mli: -------------------------------------------------------------------------------- 1 | (* {{{ COPYING *( 2 | 3 | This file is part of Merlin, an helper for ocaml editors 4 | 5 | Copyright (C) 2013 - 2015 Frédéric Bour 6 | Thomas Refis 7 | Simon Castellan 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a 10 | copy of this software and associated documentation files (the "Software"), 11 | to deal in the Software without restriction, including without limitation the 12 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 13 | sell copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in 17 | all copies or substantial portions of the Software. 18 | 19 | The Software is provided "as is", without warranty of any kind, express or 20 | implied, including but not limited to the warranties of merchantability, 21 | fitness for a particular purpose and noninfringement. In no event shall 22 | the authors or copyright holders be liable for any claim, damages or other 23 | liability, whether in an action of contract, tort or otherwise, arising 24 | from, out of or in connection with the software or the use or other dealings 25 | in the Software. 26 | 27 | )* }}} *) 28 | 29 | val token: Lexing.lexbuf -> Parser_raw.token 30 | -------------------------------------------------------------------------------- /tests/test-dirs/locate/issue1398.t/run.t: -------------------------------------------------------------------------------- 1 | Test locating definition of let-based binding operator, from reified syntax: 2 | 3 | $ $MERLIN single locate -position 3:11 ./issue1398.ml < ./issue1398.ml 4 | { 5 | "class": "return", 6 | "value": { 7 | "file": "*buffer*", 8 | "pos": { 9 | "line": 1, 10 | "col": 4 11 | } 12 | }, 13 | "notifications": [] 14 | } 15 | 16 | Test locating definition of and-based binding operator, from reified syntax: 17 | 18 | $ $MERLIN single locate -position 3:20 ./issue1398.ml < ./issue1398.ml 19 | { 20 | "class": "return", 21 | "value": { 22 | "file": "*buffer*", 23 | "pos": { 24 | "line": 2, 25 | "col": 4 26 | } 27 | }, 28 | "notifications": [] 29 | } 30 | 31 | Test locating definition of let-based binding operator, from operator syntax: 32 | 33 | $ $MERLIN single locate -position 4:0 ./issue1398.ml < ./issue1398.ml 34 | { 35 | "class": "return", 36 | "value": { 37 | "file": "*buffer*", 38 | "pos": { 39 | "line": 1, 40 | "col": 4 41 | } 42 | }, 43 | "notifications": [] 44 | } 45 | 46 | Test locating definition of and-based binding operator, from operator syntax: 47 | 48 | $ $MERLIN single locate -position 4:12 ./issue1398.ml < ./issue1398.ml 49 | { 50 | "class": "return", 51 | "value": { 52 | "file": "*buffer*", 53 | "pos": { 54 | "line": 2, 55 | "col": 4 56 | } 57 | }, 58 | "notifications": [] 59 | } 60 | -------------------------------------------------------------------------------- /src/ocaml/typing/printpat.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* OCaml *) 4 | (* *) 5 | (* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) 6 | (* *) 7 | (* Copyright 1996 Institut National de Recherche en Informatique et *) 8 | (* en Automatique. *) 9 | (* *) 10 | (* All rights reserved. This file is distributed under the terms of *) 11 | (* the GNU Lesser General Public License version 2.1, with the *) 12 | (* special exception on linking described in the file LICENSE. *) 13 | (* *) 14 | (**************************************************************************) 15 | 16 | 17 | 18 | val pretty_const 19 | : Asttypes.constant -> string 20 | val top_pretty 21 | : Format.formatter -> 'k Typedtree.general_pattern -> unit 22 | val pretty_pat 23 | : 'k Typedtree.general_pattern -> unit 24 | val pretty_line 25 | : Format.formatter -> 'k Typedtree.general_pattern list -> unit 26 | val pretty_matrix 27 | : Format.formatter -> 'k Typedtree.general_pattern list list -> unit 28 | -------------------------------------------------------------------------------- /upstream/ocaml_413/typing/printpat.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* OCaml *) 4 | (* *) 5 | (* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) 6 | (* *) 7 | (* Copyright 1996 Institut National de Recherche en Informatique et *) 8 | (* en Automatique. *) 9 | (* *) 10 | (* All rights reserved. This file is distributed under the terms of *) 11 | (* the GNU Lesser General Public License version 2.1, with the *) 12 | (* special exception on linking described in the file LICENSE. *) 13 | (* *) 14 | (**************************************************************************) 15 | 16 | 17 | 18 | val pretty_const 19 | : Asttypes.constant -> string 20 | val top_pretty 21 | : Format.formatter -> 'k Typedtree.general_pattern -> unit 22 | val pretty_pat 23 | : 'k Typedtree.general_pattern -> unit 24 | val pretty_line 25 | : Format.formatter -> 'k Typedtree.general_pattern list -> unit 26 | val pretty_matrix 27 | : Format.formatter -> 'k Typedtree.general_pattern list list -> unit 28 | -------------------------------------------------------------------------------- /upstream/ocaml_414/typing/printpat.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* OCaml *) 4 | (* *) 5 | (* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) 6 | (* *) 7 | (* Copyright 1996 Institut National de Recherche en Informatique et *) 8 | (* en Automatique. *) 9 | (* *) 10 | (* All rights reserved. This file is distributed under the terms of *) 11 | (* the GNU Lesser General Public License version 2.1, with the *) 12 | (* special exception on linking described in the file LICENSE. *) 13 | (* *) 14 | (**************************************************************************) 15 | 16 | 17 | 18 | val pretty_const 19 | : Asttypes.constant -> string 20 | val top_pretty 21 | : Format.formatter -> 'k Typedtree.general_pattern -> unit 22 | val pretty_pat 23 | : 'k Typedtree.general_pattern -> unit 24 | val pretty_line 25 | : Format.formatter -> 'k Typedtree.general_pattern list -> unit 26 | val pretty_matrix 27 | : Format.formatter -> 'k Typedtree.general_pattern list list -> unit 28 | -------------------------------------------------------------------------------- /tests/test-dirs/short-paths.t/test.ml: -------------------------------------------------------------------------------- 1 | (* *** #670 *** *) 2 | 3 | module type S = sig 4 | class virtual x : object 5 | method private virtual release : unit 6 | end 7 | end 8 | 9 | module Make (C : S) = struct 10 | 11 | class c = 12 | object 13 | method private release = () 14 | end 15 | 16 | let x = 3 17 | end 18 | 19 | (* *** #843 *** *) 20 | 21 | class a x = object method x = x end and b x = a x 22 | 23 | class a x = object end and b = object inherit a end 24 | 25 | (* *** #907 *** *) 26 | 27 | class test ?a = 28 | object 29 | method b = c 30 | end 31 | 32 | (* the following cases do not trigger error *) 33 | 34 | class test a = 35 | object 36 | method b = c 37 | end 38 | 39 | class test ?a = 40 | object 41 | method b = () 42 | end 43 | 44 | (* *** Don't select deprecated paths *** *) 45 | 46 | include struct 47 | [@@@warning "-3"] 48 | 49 | module M = struct 50 | type t = T 51 | [@@deprecated "bad"] 52 | end 53 | 54 | type t = M.t 55 | [@@deprecated "bad"] 56 | 57 | module N = struct 58 | module O = struct 59 | type t = M.t 60 | end 61 | end 62 | 63 | let f (x : t) : unit = x 64 | 65 | end 66 | 67 | (* *** #999 *** *) 68 | 69 | module type S = sig 70 | type t 71 | 72 | val foo : int -> t 73 | end 74 | 75 | module Functor (S: S) : sig 76 | val bar : int -> S.t 77 | end = struct 78 | let bar i = 79 | S.foo i 80 | end 81 | 82 | module Bar = Functor (struct 83 | type t = int 84 | 85 | let foo _i = "haha" 86 | end) 87 | 88 | (* #1082 *) 89 | 90 | let x : Dep.M.t = 5 91 | -------------------------------------------------------------------------------- /src/frontend/query_commands.mli: -------------------------------------------------------------------------------- 1 | 2 | (* {{{ COPYING *( 3 | 4 | This file is part of Merlin, an helper for ocaml editors 5 | 6 | Copyright (C) 2013 - 2015 Frédéric Bour 7 | Thomas Refis 8 | Simon Castellan 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a 11 | copy of this software and associated documentation files (the "Software"), 12 | to deal in the Software without restriction, including without limitation the 13 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 14 | sell copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in 18 | all copies or substantial portions of the Software. 19 | 20 | The Software is provided "as is", without warranty of any kind, express or 21 | implied, including but not limited to the warranties of merchantability, 22 | fitness for a particular purpose and noninfringement. In no event shall 23 | the authors or copyright holders be liable for any claim, damages or other 24 | liability, whether in an action of contract, tort or otherwise, arising 25 | from, out of or in connection with the software or the use or other dealings 26 | in the Software. 27 | 28 | )* }}} *) 29 | 30 | exception No_nodes 31 | 32 | val dispatch : Mpipeline.t -> 'a Query_protocol.t -> 'a 33 | -------------------------------------------------------------------------------- /tests/test-dirs/server-tests/typer-cache/current-level.t/run.t: -------------------------------------------------------------------------------- 1 | The server might already be running, we kill it to make sure we start from a 2 | clean slate: 3 | $ $MERLIN server stop-server 4 | 5 | Then we can look at the current level and whether it's being reset between 6 | buffers, and different runs for the same buffer: 7 | 8 | $ echo "let f x = x" | \ 9 | > $MERLIN server dump -what current-level -filename test.ml 10 | { 11 | "class": "return", 12 | "value": 0, 13 | "notifications": [] 14 | } 15 | 16 | $ echo "let f x = x" | \ 17 | > $MERLIN server dump -what current-level -filename test.ml 18 | { 19 | "class": "return", 20 | "value": 0, 21 | "notifications": [] 22 | } 23 | 24 | $ echo "type u= Uouo let f x = x type t = Toto" | \ 25 | > $MERLIN server dump -what current-level -filename test.ml 26 | { 27 | "class": "return", 28 | "value": 2, 29 | "notifications": [] 30 | } 31 | 32 | $ echo "let f x = x" | \ 33 | > $MERLIN server dump -what current-level -filename test.ml 34 | { 35 | "class": "return", 36 | "value": 2, 37 | "notifications": [] 38 | } 39 | 40 | 41 | $ echo "let f x = x" | \ 42 | > $MERLIN server dump -what current-level -filename other_test.ml 43 | { 44 | "class": "return", 45 | "value": 0, 46 | "notifications": [] 47 | } 48 | 49 | 50 | $ echo "let f x = x" | \ 51 | > $MERLIN server dump -what current-level -filename test.ml 52 | { 53 | "class": "return", 54 | "value": 2, 55 | "notifications": [] 56 | } 57 | 58 | $ $MERLIN server stop-server 59 | -------------------------------------------------------------------------------- /tests/test-dirs/pp/simple-pp.t: -------------------------------------------------------------------------------- 1 | $ $MERLIN single errors -pp cat -filename test.ml < let x : int = "hello" 3 | > EOF 4 | { 5 | "class": "return", 6 | "value": [ 7 | { 8 | "start": { 9 | "line": 1, 10 | "col": 14 11 | }, 12 | "end": { 13 | "line": 1, 14 | "col": 21 15 | }, 16 | "type": "typer", 17 | "sub": [], 18 | "valid": true, 19 | "message": "This expression has type string but an expression was expected of type int" 20 | } 21 | ], 22 | "notifications": [] 23 | } 24 | $ $MERLIN single errors -pp 'cpp -Wno-everything -E' -filename test.ml < #ifndef FOO 26 | > let x : int = "hello" 27 | > #else 28 | > let x : int = 42 29 | > #endif 30 | > EOF 31 | { 32 | "class": "return", 33 | "value": [ 34 | { 35 | "start": { 36 | "line": 2, 37 | "col": 14 38 | }, 39 | "end": { 40 | "line": 2, 41 | "col": 21 42 | }, 43 | "type": "typer", 44 | "sub": [], 45 | "valid": true, 46 | "message": "This expression has type string but an expression was expected of type int" 47 | } 48 | ], 49 | "notifications": [] 50 | } 51 | $ $MERLIN single errors -pp 'cpp -Wno-everything -E' -filename test.ml < #ifdef FOO 53 | > let x : int = "hello" 54 | > #else 55 | > let x : int = 42 56 | > #endif 57 | > EOF 58 | { 59 | "class": "return", 60 | "value": [], 61 | "notifications": [] 62 | } 63 | -------------------------------------------------------------------------------- /src/analysis/ptyp_of_type.mli: -------------------------------------------------------------------------------- 1 | type signature_elt = 2 | | Item of Types.signature_item 3 | | Type of Asttypes.rec_flag * Parsetree.type_declaration list 4 | 5 | val module_type : Types.module_type -> Parsetree.module_type 6 | 7 | val core_type : Types.type_expr -> Parsetree.core_type 8 | 9 | val modtype_declaration : 10 | Ident.t -> 11 | Types.modtype_declaration -> 12 | Parsetree.module_type_declaration 13 | 14 | val module_declaration : 15 | Ident.t -> Types.module_declaration -> Parsetree.module_declaration 16 | 17 | val signature_item : Types.signature_item -> Parsetree.signature_item 18 | 19 | val extension_constructor : 20 | Ident.t -> Types.extension_constructor -> Parsetree.extension_constructor 21 | 22 | val value_description : 23 | Ident.t -> Types.value_description -> Parsetree.value_description 24 | 25 | val label_declaration : Types.label_declaration -> Parsetree.label_declaration 26 | 27 | val constructor_arguments : 28 | Types.constructor_arguments -> Parsetree.constructor_arguments 29 | 30 | val constructor_declaration : 31 | Types.constructor_declaration -> Parsetree.constructor_declaration 32 | 33 | val type_declaration : 34 | Ident.t -> Types.type_declaration -> Parsetree.type_declaration 35 | 36 | val signature : Types.signature -> Parsetree.signature 37 | 38 | (** [group_items sig_items] groups items from a signature in a more meaningful 39 | way: type declaration of the same recursive type are group together and items 40 | following a class or class_type items are discarded *) 41 | val group_items : Types.signature_item list -> signature_elt list 42 | -------------------------------------------------------------------------------- /upstream/ocaml_413/utils/terminfo.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* OCaml *) 4 | (* *) 5 | (* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) 6 | (* *) 7 | (* Copyright 1996 Institut National de Recherche en Informatique et *) 8 | (* en Automatique. *) 9 | (* *) 10 | (* All rights reserved. This file is distributed under the terms of *) 11 | (* the GNU Lesser General Public License version 2.1, with the *) 12 | (* special exception on linking described in the file LICENSE. *) 13 | (* *) 14 | (**************************************************************************) 15 | 16 | (** Basic interface to the terminfo database 17 | 18 | {b Warning:} this module is unstable and part of 19 | {{!Compiler_libs}compiler-libs}. 20 | 21 | *) 22 | 23 | type status = 24 | | Uninitialised 25 | | Bad_term 26 | | Good_term 27 | 28 | val setup : out_channel -> status 29 | val num_lines : out_channel -> int 30 | val backup : out_channel -> int -> unit 31 | val standout : out_channel -> bool -> unit 32 | val resume : out_channel -> int -> unit 33 | -------------------------------------------------------------------------------- /upstream/ocaml_414/utils/terminfo.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* OCaml *) 4 | (* *) 5 | (* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) 6 | (* *) 7 | (* Copyright 1996 Institut National de Recherche en Informatique et *) 8 | (* en Automatique. *) 9 | (* *) 10 | (* All rights reserved. This file is distributed under the terms of *) 11 | (* the GNU Lesser General Public License version 2.1, with the *) 12 | (* special exception on linking described in the file LICENSE. *) 13 | (* *) 14 | (**************************************************************************) 15 | 16 | (** Basic interface to the terminfo database 17 | 18 | {b Warning:} this module is unstable and part of 19 | {{!Compiler_libs}compiler-libs}. 20 | 21 | *) 22 | 23 | type status = 24 | | Uninitialised 25 | | Bad_term 26 | | Good_term 27 | 28 | val setup : out_channel -> status 29 | val num_lines : out_channel -> int 30 | val backup : out_channel -> int -> unit 31 | val standout : out_channel -> bool -> unit 32 | val resume : out_channel -> int -> unit 33 | --------------------------------------------------------------------------------