类 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
公共类方法
# File lib/syntax_suggest/block_expand.rb, line 34 def initialize(code_lines:) @code_lines = code_lines end
公共实例方法
主要接口。扩展当前缩进,然后扩展到更低的缩进级别。
# 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
将代码扩展到下一个较低的缩进级别。
例如
1 def dog 2 print "dog" 3 end
如果一个块从第 2 行开始,那么它已经捕获了所有“邻居”(相同或更高缩进级别的代码)。为了继续扩展,这个块必须捕获第 1 行和第 3 行,它们位于不同的缩进级别。
此方法允许完全扩展的块降低其缩进级别(以便它们可以扩展以捕获更多向上和向下的代码)。它以保守的方式执行此操作,因为目前没有撤消功能。
# 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
邻居是指位于当前缩进行或其上方的代码。
首先,我们构建一个包含所有邻居的块。如果我们无法进一步扩展,那么我们将降低缩进阈值并通过缩进进行扩展,即“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:扩展/获取其他逻辑块
一旦搜索算法将所有行转换为给定缩进级别的块,它将“扩展缩进”。一旦生成的块作为邻居扩展,我们就会开始看到邻居是其他逻辑块,即一个块的邻居可能是另一个方法或类(带有关键字/结尾的东西)。
例如
1 def bark 2 3 end 4 5 def sit 6 end
在这种情况下,如果第 4、5 和 6 行在一个块中,当它尝试扩展邻居时,它将向上扩展。如果它在第 2 或 3 行之后停止,可能会导致问题,因为存在有效的 kw/end 对,但该块将在没有它的情况下进行检查。
我们尝试使用下面的“lookahead_balance_one_line”来解决这个边缘情况。
# 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
可管理的 rspec 错误
# File lib/syntax_suggest/block_expand.rb, line 161 def inspect "#<SyntaxSuggest::CodeBlock:0x0000123843lol >" end