是否可以获取带引号的字符串文字的行号?

Is it possible to get the line number of a quoted string literal?

我正在为 Elixir 编写一个 linter,它主要通过检查 return 从 Code.string_to_quoted/2 编辑的 AST 来工作。当我的应用程序发现某些被视为违反样式的内容时,我会使用在节点元数据中找到的行号进行报告。

字符串是其引用形式相同的文字之一,因此没有元数据。只看字符串,不能从周围的表达式中提取行号,如何获取行号

比如我要这个字符串

~s(\n"\"")

检查时在第 2 行报告错误,但 return 值没有行号。

iex(18)> Code.string_to_quoted ~S(\n"\""), lines: true
{:ok, "\""}

您不会获得文字的行号,因为它们表示为它们自己。它适用于其他一切:

iex(1)> Code.string_to_quoted "a"
{:ok, {:a, [line: 1], nil}}

虽然无法直接从引用的表达式中获取行号,但可以从标记化的源代码中获取字符串文字的行号。

Elixir 编译器的分词器实际上是标准库的一部分,可以通过 :elixir_tokenizer 模块访问,如下所示:

source_string
|> String.to_char_list
|> :elixir_tokenizer.tokenize( 1, [] )

如果您有此代码:

IO.puts "Hello, world!"

你会得到这样的回报:

{:ok, 2,
[{:aliases, 1, [:IO]}, {:., 1}, {:identifier, 1, :puts},
  {:bin_string, 1, ["Hello, world!"]}, {:eol, 1}]}

:bin_string 元组中的第二项是行号。