【问题标题】:Print module signature of a file using Merlin使用 Merlin 打印文件的模块签名
【发布时间】:2018-07-09 23:57:33
【问题描述】:

使用 Merlin 2.5.4,在我的项目中打印 OCaml 文件签名的正确方法是什么?例如,假设我有:

(* foo.ml *)
let x = 1

我想得到:

val x : int

什么是正确的命令(或命令序列)?

我尝试过的:

我将文件暂时包装在一个子模块中:module Foo = struct let x = 1 end,然后运行:

$ ocamlmerlin
["type","expression","Foo","at",{"line":1,"col":7}]

但我明白了:

["error",{"start":{"line":1,"col":0},"end":{"line":1,"col":3},"type":"type","sub":[],"valid":true,"message":"Error: Unbound constructor Foo"}]

这是有道理的,因为我实际上并没有提到我正在查询哪个文件,查询 (https://github.com/ocaml/merlin/blob/master/doc/dev/OLD-PROTOCOL.md#type-checking) 也不允许我这样做。

E 我应该提一下,我使用的是 BuckleScript,而不是 ocamlc,而且 ocamlc -i 仅在我指定我的模块及其所有模块依赖项时才有效;我正在寻找能够自动管理这些依赖项的东西。

【问题讨论】:

  • 仅供参考,-i 编译器选项显示源的签名,即ocamlc -i foo.ml
  • @camlspotter 更新了问题以澄清????
  • 您可以将您的项目加载到顶层和#show Foo(或#mod_use "foo.ml"),这将打印签名。
  • @gsg 这不适用于 BuckleScript 模块,因为它们不会被编译为普通的 OCaml 对象文件。

标签: ocaml bucklescript merlin


【解决方案1】:

让 Merlin 输出推断出的模块签名的一种方法是向它提供一系列命令(如其协议中所述 https://github.com/ocaml/merlin/blob/master/doc/dev/OLD-PROTOCOL.md#type-checking ),这些命令首先定义模块,然后询问其签名。我们可以准备一个包含此命令序列的临时文件,并将其作为标准输入提供给 Merlin。

棘手的部分是:用正确的命令包装输入;转义输入文件中的双引号字符,以免它们与 Merlin 的输入格式混合;并展开输出以丢弃 Merlin 的协议格式。以下是关键命令:

it=~/tmp/it

echo '["tell","start","end","module It = struct' >$it
sed 's/"/\\"/g' ${1%i} >>$it
echo ' end let () = ()"]' >>$it
echo '["type","expression","It","at","end"]' >>$it

ocamlmerlin <$it | sed -e '/^\["return",true\]$/d' -e 's/^\["return","sig *//' -e 's/ *end"\]$//' -e 's/\\"/"/g' -e 's/\\n/\
/g' | sed -e '/^ *$/d' -e 's/^  //'

注意事项:

  • 以上假设是一个带有touchsed 的Unix-y 系统,并且在命令路径中还有ocamlmerlin
  • Merlin 不会在其输出中保留 OCaml 属性 ([@...])
  • 仅适用于 OCaml 语法,但可以适应 Reason 语法

可以在https://gist.github.com/yawaramin/b86557ae81cbd019fcb9e071abe594de 找到更完整的脚本。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-30
    • 1970-01-01
    • 1970-01-01
    • 2021-02-13
    • 1970-01-01
    • 2017-04-18
    • 1970-01-01
    • 2013-04-08
    相关资源
    最近更新 更多