class SyntaxSuggest::CleanDocument

解析并清理源代码,使其成为具有词法意识的文档

在内部,文档由一个数组表示,每个索引包含一个 CodeLine,对应于源代码中的一行。

算法有三个主要阶段

  1. 净化/格式化输入源码

  2. 搜索无效代码块

  3. 将无效代码块格式化为有意义的内容

此类处理第一部分。

此类存在的原因是为了格式化输入源,以便更好地/更容易/更清晰地进行探索。

CodeSearch 在行级别运行,因此我们必须小心,不要引入单独看起来有效但删除后会触发语法错误或奇怪行为的行。

## 连接尾随斜杠

带尾随斜杠的代码在逻辑上被视为单行

1 it "code can be split" \
2    "across multiple lines" do

在这种情况下,删除第二行会产生语法错误。我们通过在内部将两行连接成一个“行”对象来解决这个问题。

## 逻辑上连续的行

可以跨越多行的代码,例如方法调用,位于不同的行上。

1 User.
2   where(name: "schneems").
3   first

删除第二行会产生语法错误。为了解决这个问题,所有行都连接成一行。

## Heredocs

heredoc 是一种定义多行字符串的方式。它们可能导致许多问题。如果将其保留为单行,解析器将尝试将内容解析为 Ruby 代码而不是字符串。即使没有这个问题,我们仍然会遇到缩进问题。

1 foo = <<~HEREDOC
2  "Be yourself; everyone else is already taken.""
3    ― Oscar Wilde
4      puts "I look like ruby code" # but i'm still a heredoc
5 HEREDOC

如果我们不连接这些行,我们的算法将认为第四行与其余部分分开,具有更高的缩进,然后先查看并删除它。

如果代码单独评估第五行,它会认为第五行是一个常量,删除它,并引入语法错误。

通过将整个 heredoc 连接成一行来解决所有这些问题。

## 注释和空白

注释会干扰词法分析器告诉我们该行在逻辑上属于下一行的方式。这是有效的 Ruby,但结果的词法输出与之前不同。

1 User.
2   where(name: "schneems").
3   # Comment here
4   first

为了解决这个问题,我们可以用空行替换注释行,然后重新词法分析源代码。这种删除和重新词法分析保留了行索引和文档大小,但生成了一个更容易处理的文档。