在带有类型的注释之后运行透析器没有显示任何警告



在一个大约有6000行Erlang代码但没有类型-spec()注释的项目中,我尝试了以下操作:

typer --annotate *.erl

我用带注释的文件替换了所有的*.erl文件并运行

dialyzer --src -c *.erl

我期望得到很多警告(第一次运行dialyzer/type组合),但在做了它的事情之后,所有dialyzer报告的都是user_default中同时不存在的函数的2个旧调用。

没有其他默认警告触发。

是我用错了吗?还是像这样的结果很常见?

是自动注释与typerdialyzer的组合不那么有用,还是我只是幸运,我的代码没有问题?


旁注:我不得不注释掉3或4个-spec(),因为dialyzer崩溃了。

我正在使用Dialyzer v2.2.0和TypEr v0.1.7.4从Erlang R13B04

作为在erlang-bugs列表中报告错误的副作用,我从dialyzer和type的发明者Kostis Sagonas那里得到了详细的回答。

对于我的侧面问题,我得到了以下伟大而详细的答案:

2011年5月1日星期日下午5:53,Kostis Sagonas写道:

Peer Stritzinger写道:

顺便说一句:在做——注释时没有得到任何警告是正常的吗在类型和透析器中,没有手动调整规格

是的。实际上,type只是透析器基本类型推断的前端(即没有警告识别组件)。

在我看来,如果你不打算手动"按摩"你得到的规格并为其中一些提供更多信息,那么这样做就没有什么意义了。看看你以前的计划。这两个<<:64,:_*8>>类型指的是同一个量,如果您像下面这样引入一个类型,可以更好地表达这一事实:

  -type packet() :: <<_:64,_:_*8>>,

通道类似:

  -type channel() :: atom() | pid() |{atom(),_}.

,那么规格说明已经看起来更好了。此外,透透器/类型没有关于你打算在函数recv/3的第二个参数中使用什么类型的乐趣的信息,但你这样做!从代码中可以清楚地看出,它接受#can_pkt{}记录,那么为什么不为它的字段添加适当的类型并为它引入类型呢?

  -record(can_pkt, {id :: id(), data :: binary(), timestamp :: ts()}).
  -type can_pkt() :: #can_pkt{}.

那么规格可以看起来更好:

  -spec recv(packet(), fun((can_pkt()) -> R), channel()) -> R.
  -spec decode(packet()) -> can_pkt().

,请注意,我使用了占位符类型变量R来表示函数recv/2返回第二个参数所返回的类型。你可能知道这个类型是什么,所以你也应该为它引入一个类型,并使用它的适当名称。

希望有帮助,

科斯

p。很遗憾你在erlang-bugs中发布了这篇文章,因为在我看来,上面包含的信息比实际的bug更有趣。

因为他引用了我在bug报告中包含的代码片段,所以我在这里包含了它。以下代码片段由typer --annotate自动注释:

-record(can_pkt, {id, data, timestamp}).
-spec recv(<<_:64,_:_*8>>,fun((_) -> 
      any()),atom() | pid() | {atom(),_}) -> any().
recv(Packet, Recv_fun, Chan) ->
    P = decode(Packet),
    #can_pkt{id=Can_id, data=Can_data}=P,
    Recv_fun(P).
-spec decode(<<_:64,_:_*8>>) -> 
      #can_pkt{id::<<_:11>>,data::binary(),timestamp::char()}.
decode(<<_:12, Len:4, Timestamp:16,
        0:3, Id:11/bitstring, 0:18,
        Data:Len/binary, _/binary>>) ->
    #can_pkt{id=Id, data=Data, timestamp=Timestamp}.

相关内容

  • 没有找到相关文章

最新更新