问题标签 [dialyzer]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
206 浏览

erlang - 为什么 Dialyzer 相信具有过于具体的返回类型的规范?

我希望添加规范永远不会降低安全性,但这正是在以下情况下发生的情况。

在下面的代码中,Dialyzer(错误地)相信我 bar 的返回类型是1. 这导致它说 foo() 中的模式永远无法匹配——不正确的建议,如果注意,会引入运行时错误!

删除规范以bar/0解决问题——但为什么 Dialyzer 信任我?Dialyzer 在这里违反了它的“无误报”承诺:它在没有错误时发出警告。并且(更糟糕的是)Dialyzer 推动引入了一个新错误。

0 投票
1 回答
105 浏览

erlang - Dialyzer 警告 no_exit 构建不良记录 - 这是一个错误吗?

当 Dialyzer 遇到未初始化必填字段的记录文字时,它认为控制流在记录文字所在的行停止。

例子:

错误:

这是一个错误吗?Erlang 的运行时语义与 Dialyzer 对它们的建模方式匹配:ERTS(无论好坏!)都在不断前进,愉快地将原子“未定义”分配给任何未初始化的字段。

澄清:我的意思是,在可行的情况下,最好让静态检查反映 Erlang 在运行时的工作方式。

那么这是透析器的错误吗?

Dialyzer 处理这些错误初始化记录的方式是有害的,因为它会触发一连串虚假警告——当 Dialyzer 认为某行函数foo不可访问时,任何只能从 from 可访问的函数foo也被视为已死。

0 投票
1 回答
82 浏览

erlang - 强制转换为 `any()` 是让 Dialyzer 接受 ETS 匹配模式的好解决方案吗?

选择any()一个让 Dialyzer 接受 ETS 匹配模式的好解决方案吗?

Dialyzer 和 match 规格不能很好地配合使用,并且似乎没有标准的解决方案:

这是我正在考虑的解决方案的完整示例。如果matcher('_')在最后一行更改为“_”,则 Dialyzer 会抱怨记录构造错误,但该matcher/1功能似乎一切正常:

这是有效的,因为 Dialyzer 不能静态地判断出不可达的第一个子句matcher/1是不可达的。由于binary_to_term/1返回any(),Dialyzer 推断返回类型matcher/1为 be any()

在使用匹配规范时,这个技巧是让 Dialyzer 开心的好方法吗?“好”是指:

  • 运行时成本低
  • 几支长枪
  • 没有更好(更安全、更快、更符合人体工程学)的方式

我看了看它的实现node()并认为它只是一个指针取消引用,所以成本应该很低。并且 '$ will never match' 真的永远不会匹配,因为node() 总是返回一个带有 an @in it的原子。但必须有更好的方法。

这里确实有两个问题,我结合起来避免了XY 问题

  1. 上面的技术是让 Dialyzer 将某些东西视为 的好方法any()吗?
  2. 将 Dialyzer 视为处理matcher('_')匹配any()规范的良好解决方案吗?
0 投票
2 回答
71 浏览

erlang - 如何让 Dialyzer 接受对故意抛出的函数的调用?

我有一个函数,当它的第一个参数是 atom 时,它会故意抛出throw

此代码的简化版本是:

调用时出现透析器错误throw_or_ok

添加规格没有帮助,错误消息是相同的:

我怎样才能让 Dialyzer 接受throw_or_ok/1保证会抛出的调用?

0 投票
1 回答
116 浏览

types - `changeset()` 规范要求逻辑上不可为空的可空类型

我有以下代码:

foo根据定义,baz_id不应该是。但是,正在抱怨(使用给定的),因为默认值会将它们设置为.nil@typedialyzer@spec%__MODULE__{}nil

如果我将@type定义替换为:

那么dialyzer不会抱怨,但我不再认为某些字段不可为空。

什么是一种优雅的方式来使changeset()工作以目前的方式工作,并避免dialyzer抱怨这种特定的用途?

0 投票
1 回答
109 浏览

erlang - Elixir 中透析器的多态类型

背景

我有一个struct调用MyApp.Result,它基本上是 Result Monad 的表示。该结构旨在成为操作成功和错误的正式结构表示:

问题

在向我的一位同事展示这一点时,他提出了一个很好的观点:

我看到你在这里尝试做什么,但是当我看到一个MyApp.Result结构时,我必须检查代码以了解result字段内部的内容,以防成功。对我来说,这只是隐藏事物的另一层,如果操作成功,它并不清楚操作返回什么。

公平地说,我认为这是一个很好的观点。结果单子会隐藏计算结果,直到您需要它们。但我确实认为有一种更好的方法,一种我们仍然可以拥有一个 Result Monad 的方法,它明确显示结果字段的类型。

带透析器的多态类型

我相信我的问题的解决方案可能是透析器的多态类型。引用一篇文章:

来自Learn You Some Erlang 当我说我们可以将整数列表定义为[integer()]orlist(integer())时,那些是多态类型。它是一种接受类型作为参数的类型。

为了使我们的队列只接受整数或卡片,我们可以将其类型定义为:

所以现在我知道这在 erlang 中是可能的。如果那里有可能,那么在 Elixir 中也应该有可能。

错误

因此,我将代码更改为以下内容:

然而,这打破了。我不知道如何使用透析器在 Elixir 中表示多态类型。

问题

如何修复此代码,以便我的透析器知道 Result 是多态类型?

0 投票
1 回答
72 浏览

elixir - 使用点语法访问 struct prop 时出现 Elixir Dialyzer 错误

将我的项目更新为使用 Elixir 1.12 后,我注意到 Dialyzer 抱怨我使用点符号访问结构属性的某些地方。例如,这是我的应用程序中的一个 graphql 解析器函数:

Dialyser 突出显示了user.email !== updated_user.email带有以下错误的表达式:

The call _.'email'/() requires that _@1 is of type atom(), not {map(), map()}

知道这个错误是什么意思以及如何解决吗?

(这一切都编译并运行良好,我只是想知道为什么它似乎不满足 Dialyzer)

0 投票
0 回答
252 浏览

elixir - 如何修复依赖项中的透析器 unknown_function 错误?

我有一个大型 Elixir (1.7.4) 应用程序,并且正在运行透析器(使用 dialyxir 的最新版本)。对于似乎主要位于嵌套在我在 deps 中的包下的模块中的函数,我得到了很多 unknown_function 错误。我发现了新的 Mix.Tasks 的 How to fix Dialyzer "Callback info about the '.....' behavior is not available" 错误(我也有错误,我希望共享一个解决方案),它说我应该能够将应用程序添加到我的 mix.exs 文件中,但这似乎根本没有做任何事情。

我也有很多错误: Callback info about the Plug behaviour is not available.即使在将插件 dep 添加到上述应用程序之后。有什么明显的我做错了吗?如果它们也是依赖项,你能解释一下需要列为应用程序的内容吗?如果您有解决方案,请具体说明。我对透析器很陌生,对长生不老药也很陌生。

(ps 不得不说,透析器令人难以置信的准确性给我留下了深刻的印象。所以如果我能把这种噪音安静下来,这样我就可以真正解决问题了。到目前为止发现了一些偷偷摸摸的错误(还有很多不好的眼镜 :-( )。)

这是我在 mix.exs 中的项目定义,更改了我的应用程序名称,并添加了表达式以尝试 Aleksei 的 plt_add_apps 解决方案(到目前为止还没有工作)。

一小部分错误示例,突出显示了我尝试添加为应用程序的混合和插入依赖项、无法识别的基本类型以及未找到即插即用行为。

0 投票
1 回答
46 浏览

elixir - Elixir 行为返回实现者的结构类型

我有一种行为来抽象解析各种 Phoenix 端点的 URL 查询参数。它看起来像这样:

一个简单的实现如下所示:

我在这里真正想说的是:

  • 实现模块应该提供一个结构(调用它t()
  • 成功类型from_query_params/1应该使用那个struct t(),而不仅仅是任何 struct

我怀疑 Elixir 类型规范语言中没有办法表达这一点,但我很高兴被证明是错误的。

0 投票
1 回答
49 浏览

functional-programming - Dialyzer 不会捕获返回函数的错误

背景

在使用透析器、typespecs 和 currying 时,我能够在透析器中创建一个误报示例。

出于本MWE的目的,我正在使用diallyxir(包括版本),因为它让我的生活更轻松。dialyxir 的作者证实这对他们来说不是问题,因此目前排除了这种可能性。

环境

  • 您使用的是哪个版本的 Dialyxir?(猫 mix.lock | grep 透析器):

当前行为

给定以下代码示例:

显然输入错误,我收到一条成功消息:

预期行为

我希望透析器告诉我正确的规格是 @spec greater_than(integer()) :: (integer() -> bool()).

作为旁注(和比较,如果你愿意的话)梯度确实会发现错误。我知道比较这些工具就像比较橘子和苹果,但我认为还是值得一提。

问题

  1. 透析器不打算捕捉这种类型的错误吗?
  2. 如果它应该捕获错误,那么可能会失败吗?(是我的例子不正确,还是透析器内部的东西?)

我个人很难相信这可能是 Dialyzer 中的错误,该工具已被很多人广泛使用,我是第一个发现此错误的人。但是,我无法解释发生了什么。

帮助表示赞赏。