使用typer注释后运行透析器未显示任何警告

时间:2011-05-01 15:28:34

标签: erlang typechecking dialyzer

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

typer --annotate *.erl

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

dialyzer --src -c *.erl

我预计会收到很多警告(第一次运行透析器/ typer组合)但是在完成它之后,所有透析器报告的是user_default中的2个旧调用,同时不存在函数。

没有其他默认警告触发。

我使用它是否犯了错误,或者是这种常见的结果?

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


旁注:我必须发表评论3或4 -spec(),因为dialyzer crashed on them

我正在使用Erlang R13B04的Dialyzer v2.2.0和TypEr版本v0.1.7.4

1 个答案:

答案 0 :(得分:3)

作为报告erlang-bugs列表中的错误的副作用,我从透析器和typer的发明者Kostis Sagonas那里得到了详细的答案。

就我方面的问题而言,我得到了以下非常详尽的答案:

  

On Sun, May 1, 2011 at 5:53 PM, Kostis Sagonas wrote:

     
    

Peer Stritzinger写道:

         

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

  
     

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

     

IMO,如果您不打算手动“按摩”您获得的规格并为其中一些提供更多信息,那么这样做是非常重要的。看看你以前的程序。事实上两个< :64,:_ * 8>>如果你引入了一个类型,可以更好地表达相同数量的类型:

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

同样适用于频道:

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

然后规格看起来会更好。另外,dialyzer / typer没有关于你打算在函数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返回其第二个参数返回的乐趣类型的事实。你可能知道这个类型是什么,所以你也应该为它引入一个类型并使用它的正确名称。

     

希望这有帮助,

     

Kostis

     

PS。很遗憾你在erlang-bugs中发布了这个,因为上面包含的信息比IMO更有趣。

由于他引用了一个代码片段,我将其包含在我的错误报告中,我将其包含在此处。以下代码片段由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}.