class SyntaxSuggest::BlockExpand
Diese Klasse ist dafür verantwortlich, einen Codeblock, der sich auf einer weiten Einrückung befindet, zu nehmen und den Block dann iterativ zu vergrößern, so dass er alles innerhalb desselben Einrückungsblocks erfasst.
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"
Sobald ein Codeblock alles auf einer bestimmten Einrückungsebene erfasst hat, erweitert er sich, um die umliegenden Einrückungen zu erfassen.
block = BlockExpand.new(code_lines: code_lines)
.call(block)
block.to_s # => def dog
puts "bow" puts "wow" end
Öffentliche Klassenmethoden
Source
# File lib/syntax_suggest/block_expand.rb, line 34 def initialize(code_lines:) @code_lines = code_lines end
Öffentliche Instanzmethoden
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
Hauptschnittstelle. Erweitert die aktuelle Einrückung, bevor zu einer niedrigeren Einrückung erweitert wird
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
Erweitert den Code auf die nächst niedrigere Einrückung
Zum Beispiel
1 def dog 2 print "dog" 3 end
Wenn ein Block in Zeile 2 beginnt, hat er alle seine „Nachbarn" (Code mit gleicher oder höherer Einrückung) erfasst. Um die Erweiterung fortzusetzen, muss dieser Block Zeile eins und drei erfassen, die sich auf einer anderen Einrückungsebene befinden.
Diese Methode ermöglicht es vollständig erweiterten Blöcken, ihre Einrückungsebene zu verringern (damit sie sich erweitern können, um mehr Code nach oben und unten zu erfassen). Dies geschieht konservativ, da es keine Rückgängig-Funktion gibt (derzeit).
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
Ein Nachbar ist Code, der sich auf der aktuellen Einrückungszeile oder darüber befindet.
Zuerst erstellen wir einen Block mit allen Nachbarn. Wenn wir nicht weitergehen können, verringern wir den Einrückungsschwellenwert und erweitern ihn durch Einrückung, d.h. `expand_indent`
Behandelt zwei allgemeine Fälle.
## Fall #1: Überprüfung von Code innerhalb von Methoden/Klassen/etc.
Es ist wichtig zu beachten, dass nicht alles auf einer bestimmten Einrückungsebene als gültiger Code geparst werden kann, auch wenn es Teil von gültigem Code ist. Zum Beispiel
1 hash = {
2 name: "richard",
3 dog: "cinco",
4 }
In diesem Fall sind die Zeilen 2 und 3 Nachbarn, aber sie sind ungültig, bis `expand_indent` auf sie angewendet wird.
Wenn wir Code innerhalb einer Methode oder Klasse (auf derselben Einrückungsebene) hinzufügen, verwenden wir die leeren Zeilen, um logische Blöcke zu kennzeichnen, die vom Programmierer beabsichtigt waren. Stoppen Sie und überprüfen Sie jeden einzelnen. Zum Beispiel
1 def dog
2 print "dog"
3
4 hash = {
5 end
Wenn wir das Parsen bei leeren Zeilenumbrüchen nicht stoppen würden, könnte der Block fälschlicherweise alle Inhalte (Zeilen 2, 3 und 4) erfassen und sie als Probleme melden, anstatt nur Zeile 4.
## Fall #2: Erweiterung/Erfassung anderer logischer Blöcke
Sobald der Suchalgorithmus alle Zeilen in Blöcke auf einer bestimmten Einrückungsebene umgewandelt hat, wird `expand_indent` aufgerufen. Sobald die von diesem generierten Blöcke als Nachbarn erweitert werden, sehen wir Nachbarn als andere logische Blöcke, d.h. die Nachbarn eines Blocks können eine andere Methode oder Klasse sein (etwas mit Schlüsselwörtern/Endungen).
Zum Beispiel
1 def bark 2 3 end 4 5 def sit 6 end
In diesem Fall, wenn die Zeilen 4, 5 und 6 in einem Block sind, wenn er versucht, Nachbarn zu erweitern, wird er nach oben erweitert. Wenn er nach Zeile 2 oder 3 stoppt, kann dies zu Problemen führen, da es ein gültiges Schlüsselwort/Ende-Paar gibt, aber der Block ohne es überprüft wird.
Wir versuchen, diesen Randfall mit `lookahead_balance_one_line` unten zu lösen.
Source
# File lib/syntax_suggest/block_expand.rb, line 161 def inspect "#<SyntaxSuggest::CodeBlock:0x0000123843lol >" end
Handhabare rspec-Fehler