【问题标题】:Run of dialyzer after annotation with typer did not show any warnings使用 typer 注释后运行透析器未显示任何警告
【发布时间】:2013-04-14 04:57:45
【问题描述】:

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

typer --annotate *.erl

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

dialyzer --src -c *.erl

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

没有触发其他默认警告。

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

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


旁注:我不得不注释掉 3 或 4 个 -spec()s,因为 dialyzer crashed on them

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

【问题讨论】:

    标签: erlang typechecking dialyzer


    【解决方案1】:

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

    对于我的附带问题,我得到了以下出色而详细的答案:

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

    Peer Stitzinger 写道:

    顺便说一句:在执行 --annotate 时没有收到任何警告是否正常 在打字机中,然后在没有手动调整规范的透析器中

    是的。其实typer只是dialyzer基本类型推断的一个前端(即没有warning标识组件)。

    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 返回其第二个参数中的乐趣返回的任何类型。你可能知道这个类型是什么,所以你也应该为它引入一个类型并使用它的正确名称。

    希望这会有所帮助,

    科斯蒂斯

    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}.
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-23
      • 1970-01-01
      • 2014-12-24
      • 2011-01-06
      • 2018-03-28
      • 2016-06-25
      • 2019-01-30
      • 2013-04-08
      相关资源
      最近更新 更多