class SyntaxSuggest::BlockExpand
此类负责获取缩进较深的现有代码块,然后对其进行迭代扩展,以捕获同一缩进块内的所有内容。
def dog puts "bow" puts "wow" end
block = BlockExpand.new(code_lines: code_lines)
.call(CodeBlock.new(lines: code_lines[1]))
puts block.to_s # => puts “bow”
puts "wow"
一旦代码块捕获了给定缩进级别内的所有内容,它就会扩展以捕获周围的缩进。
block = BlockExpand.new(code_lines: code_lines)
.call(block)
block.to_s # => def dog
puts "bow" puts "wow" end
Public Class Methods
Source
# File lib/syntax_suggest/block_expand.rb, line 34 def initialize(code_lines:) @code_lines = code_lines end
Public Instance Methods
Source
# File lib/syntax_suggest/block_expand.rb, line 40 def call(block) if (next_block = expand_neighbors(block)) next_block else expand_indent(block) end end
主接口。扩展当前缩进,然后再扩展到较低的缩进
Source
# File lib/syntax_suggest/block_expand.rb, line 63 def expand_indent(block) now = AroundBlockScan.new(code_lines: @code_lines, block: block) .force_add_hidden .stop_after_kw .scan_adjacent_indent now.lookahead_balance_one_line now.code_block end
将代码扩展到下一个较低的缩进
例如
1 def dog 2 print "dog" 3 end
如果一个块从第 2 行开始,那么它已经捕获了它所有的“邻居”(相同或更高缩进的代码)。要继续扩展,这个块必须捕获第 1 行和第 3 行,这两行具有不同的缩进级别。
此方法允许完全扩展的块减少其缩进级别(以便它们可以扩展以捕获更多向上和向下的代码)。它是保守地这样做的,因为目前没有撤销机制。
Source
# File lib/syntax_suggest/block_expand.rb, line 130 def expand_neighbors(block) now = AroundBlockScan.new(code_lines: @code_lines, block: block) # Initial scan now .force_add_hidden .stop_after_kw .scan_neighbors_not_empty # Slurp up empties now .scan_while { |line| line.empty? } # If next line is kw and it will balance us, take it expanded_lines = now .lookahead_balance_one_line .lines # Don't allocate a block if it won't be used # # If nothing was taken, return nil to indicate that status # used in `def call` to determine if # we need to expand up/out (`expand_indent`) if block.lines == expanded_lines nil else CodeBlock.new(lines: expanded_lines) end end
邻居是与当前缩进行相同或更高的代码。
首先,我们构建一个包含所有邻居的块。如果我们无法进一步扩展,那么我们就降低缩进阈值并通过缩进进行扩展,即 `expand_indent`
处理两种一般情况。
## 情况 #1:检查方法/类/等内部的代码
重要的是要注意,给定缩进级别中的并非所有内容都可以解析为有效代码,即使它是有效代码的一部分。例如
1 hash = {
2 name: "richard",
3 dog: "cinco",
4 }
在这种情况下,第 2 行和第 3 行将是邻居,但它们无效,直到对它们调用 `expand_indent`。
当我们在方法或类(相同缩进级别)内添加代码时,请使用空行来表示程序员意图的逻辑块。停止并检查每一个。例如
1 def dog
2 print "dog"
3
4 hash = {
5 end
如果我们不以空新行停止解析,那么该块可能会错误地捕获所有内容(第 2、3 和 4 行),并将它们报告为问题,而不是仅报告第 4 行。
## 情况 #2:扩展/抓取其他逻辑块
一旦搜索算法将给定缩进级别中的所有行转换为块,它就会进行 `expand_indent`。一旦生成的块被扩展为邻居,我们就会开始看到邻居是其他逻辑块,即一个块的邻居可能是另一个方法或类(具有关键字/结束符的内容)。
例如
1 def bark 2 3 end 4 5 def sit 6 end
在这种情况下,如果第 4、5 和 6 行在一个块中,当它尝试扩展邻居时,它会向上扩展。如果它在第 2 或第 3 行之后停止,可能会导致问题,因为存在有效的关键字/结束对,但块将在没有它的情况下被检查。
我们尝试使用下面的 `lookahead_balance_one_line` 来解决这个边缘情况。
Source
# File lib/syntax_suggest/block_expand.rb, line 161 def inspect "#<SyntaxSuggest::CodeBlock:0x0000123843lol >" end
可管理的 rspec 错误