Class: ASTTransform::Layout
- Inherits:
-
Object
- Object
- ASTTransform::Layout
- Defined in:
- lib/ast_transform/layout.rb
Overview
Line-addressed output: text is placed at absolute line numbers, top to bottom, and the cursor never rewinds.
When a placement's target line is already behind the cursor, the text is packed (; ) onto the current line
instead — Ruby lets statements share a physical line, so alignment degrades locally and the next placement
whose target is still ahead re-anchors. Knows nothing about Ruby structure or ASTs; callers decide WHAT goes
on WHICH line, the layout owns the pad-or-pack mechanics.
Instance Method Summary collapse
-
#cursor ⇒ Object
The line number currently being written; the next fresh line would be +cursor + 1+.
-
#initialize ⇒ Layout
constructor
A new instance of Layout.
-
#pack(text) ⇒ Object
Appends
textto the current line with a;separator. -
#place(target_line, text, column: nil) ⇒ Object
Places
textattarget_linewhen the cursor hasn't passed it; otherwise packs onto the current line. -
#place_on_fresh_line(text) ⇒ Object
Appends
texton a new line unconditionally — for text that must never be;-packed after a statement (e.g. keywords). -
#to_source ⇒ String
The laid-out text, with a trailing newline.
Constructor Details
#initialize ⇒ Layout
Returns a new instance of Layout.
10 11 12 |
# File 'lib/ast_transform/layout.rb', line 10 def initialize @lines = [] end |
Instance Method Details
#cursor ⇒ Object
The line number currently being written; the next fresh line would be +cursor + 1+.
15 16 17 |
# File 'lib/ast_transform/layout.rb', line 15 def cursor @lines.size end |
#pack(text) ⇒ Object
Appends text to the current line with a ; separator. The last line is never blank here: padding blanks
are only created inside place, which immediately overwrites the padded line.
45 46 47 48 49 50 51 |
# File 'lib/ast_transform/layout.rb', line 45 def pack(text) if @lines.empty? @lines << text else @lines[-1] = "#{@lines.last}; #{text}" end end |
#place(target_line, text, column: nil) ⇒ Object
Places text at target_line when the cursor hasn't passed it; otherwise packs onto the current line.
Multi-line text advances the cursor by its height. When opening a fresh line, the first line is indented to
column — cosmetic only (leading whitespace is never significant in emitted code), but it keeps the artifact
visually close to the source. Packed text ignores the column, as do continuation lines (they keep their own
relative indentation).
24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/ast_transform/layout.rb', line 24 def place(target_line, text, column: nil) first, *rest = text.split("\n") if target_line && target_line > @lines.size @lines << '' while @lines.size < target_line @lines[-1] = indented(first, column) else pack(first) end @lines.concat(rest) end |
#place_on_fresh_line(text) ⇒ Object
Appends text on a new line unconditionally — for text that must never be ;-packed after a statement
(e.g. keywords).
39 40 41 |
# File 'lib/ast_transform/layout.rb', line 39 def place_on_fresh_line(text) @lines << text end |
#to_source ⇒ String
Returns the laid-out text, with a trailing newline.
54 55 56 |
# File 'lib/ast_transform/layout.rb', line 54 def to_source "#{@lines.join("\n")}\n" end |