Typerとの注釈後のDialyzerの実行は、警告を表示しませんでした
-
27-10-2019 - |
質問
約6000行のerlangコードがあるがタイプがないプロジェクトでは -spec()
注釈まだ次のことを試しました:
typer --annotate *.erl
私はすべてを交換しました *.erl
注釈付きのファイルと実行されたファイル
dialyzer --src -c *.erl
私は多くの警告を得ることを期待していました(初めてdialyzer/typerの組み合わせを実行しました)が、そのことをした後、すべてのDialyzerが報告したのは、存在しない機能への2つの古いコールでした。
デフォルトの警告の他にトリガーはありませんでした。
私はそれを使用して間違いを犯しましたか、それともこのような結果ですか?
自動注釈の組み合わせです typer
と dialyzer
それほど役に立たないか、私はただ幸運で、私のコードには問題がありませんか?
サイドノート:3または4をコメントしなければなりませんでした -spec()
sなぜなら dialyzer
彼らにクラッシュした.
Erlang R13B04のDialyzer V2.2.0とTyperバージョンv0.1.7.4を使用しています
解決
Erlang-Bugsリストにバグを報告する副作用として、DialyzerとTyperの発明者であるKostis Sagonasから詳細な答えが得られました。
私の側の質問に、私は次の素晴らしい詳細な答えを得ました:
2011年5月1日午後5時53分、コスティスサゴナスは次のように書いています。
ピアストライトジンガーは書いた:
ところで:ただのときに警告を受けないのは普通ですか?タイパーではアンドテートしてから、手動で微調整された仕様のない透析装置
はい。実際、TyperはDialyzerの基本的なタイプの推論のフロントエンドにすぎません(つまり、警告識別コンポーネントのない)。
IMO、あなたが手に入れる仕様を手動で「マッサージ」し、それらのいくつかにもっと情報を提供するつもりがない場合、これを行うことにはほとんど意味がありません。以前のプログラムをご覧ください。 2つ<:64,:_*8 >>タイプを次のように導入すると、同じ量を参照していました。
-type packet() :: <<_:64,_:_*8>>,
同様にチャネルについて:
-type channel() :: atom() | pid() |{atom(),_}.
そして、スペックはすでに良く見えるでしょう。また、Dialyzer/Typerには、関数の2番目の引数で使用することを意図していることに関する情報はありません
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
2番目の引数での楽しさが戻ってくるタイプを返します。おそらくこのタイプが何なのか知っているので、そのタイプを導入して、その適切な名前を使用する必要があります。お役に立てれば、
コスティス
詩上記に含まれる情報は実際のバグよりも興味深いので、これをErlang-Bugsに投稿したのは残念です。
彼はコードフラグメントを参照しているため、バグレポートに含めました。ここに含めます。次のコードフラグメントは、自動的に注釈が付けられました 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}.