class SyntaxSuggest::CleanDocument

解析并将源代码清理为词法感知的文档

在内部,文档由一个数组表示,每个索引包含一个 CodeLine,它与源代码中的一行相关联。

算法主要有三个阶段

  1. 清理/格式化输入源代码

  2. 搜索无效的代码块

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

这个类处理第一部分。

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

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

## 连接尾部斜杠

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

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

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

## 逻辑上连续的行

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

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

删除第 2 行可能会引入语法错误。为了解决这个问题,所有行都连接成一行。

## Here 文档

Here 文档是一种定义多行字符串的方法。它们可能会导致许多问题。如果将其保留为单行,解析器将尝试将内容解析为 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

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

如果代码单独计算第 5 行,它会认为第 5 行是常量,删除它,并引入语法错误。

通过将整个 Here 文档连接成一行,可以解决所有这些问题。

## 注释和空格

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

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

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