Class: ASTTransform::LineAlignedEmitter
- Inherits:
-
Object
- Object
- ASTTransform::LineAlignedEmitter
- Defined in:
- lib/ast_transform/line_aligned_emitter.rb
Overview
Emits a transformed AST as text in which every loc-carrying statement occupies its original source line, so that backtraces, breakpoints and debugger display are correct by construction — CRuby derives line numbers from physical text position, so placement is our line table.
Placement policy over statement sequences:
- Statement has loc: target its source line — the Layout pads to reach it, or packs (
;) when the cursor has already passed it. A user statement packing means the transform moved it — the alignment auditor's concern, not a runtime failure. - No loc: pack onto the current line — synthetic code has no source-line truth to preserve.
The emitter owns the Ruby knowledge: walking statement structure, deciding which line each node targets, and
that keywords can never be ;-packed. The pad-or-pack mechanics live in Layout; statement-to-text rendering
(and its isolation workarounds) in StatementRenderer — both created per emission, so the emitter itself is
stateless and an instance is a reusable collaborator.
Thunk nodes are lowered (ThunkLowering) before layout; the emitter's postcondition is that no custom node type (ast_* markers or types registered on ASTTransform::Node) crosses the unparse boundary — they are IR between stages that understand them.
Defined Under Namespace
Classes: UnloweredNodeTypeError
Constant Summary collapse
- RECURSIVE_CONTAINER_TYPES =
Containers the emitter recurses into so nested statements align; every other node renders as an Unparser blob at its head line.
[:class, :module, :sclass, :def, :defs, :block, :numblock, :itblock, :kwbegin].freeze
- BODY_INDEXES =
{ class: 2, module: 1, sclass: 1, def: 2, defs: 3, block: 2, numblock: 2, itblock: 2 }.freeze
- ASSIGNMENT_TYPES =
Assignments whose value is a block (e.g. the lowered thunk proc) recurse into the block so its body statements align.
[:lvasgn, :ivasgn, :gvasgn, :casgn].freeze
- BLOCK_VALUE_TYPES =
[:block, :numblock, :itblock].freeze
Instance Method Summary collapse
-
#emit(ast, source_path) ⇒ String
Transformed source, line-aligned.
-
#initialize(thunk_lowering: ThunkLowering.new) ⇒ LineAlignedEmitter
constructor
A new instance of LineAlignedEmitter.
Constructor Details
#initialize(thunk_lowering: ThunkLowering.new) ⇒ LineAlignedEmitter
Returns a new instance of LineAlignedEmitter.
45 46 47 |
# File 'lib/ast_transform/line_aligned_emitter.rb', line 45 def initialize(thunk_lowering: ThunkLowering.new) @thunk_lowering = thunk_lowering end |
Instance Method Details
#emit(ast, source_path) ⇒ String
Returns transformed source, line-aligned.
54 55 56 57 58 59 60 61 62 |
# File 'lib/ast_transform/line_aligned_emitter.rb', line 54 def emit(ast, source_path) lowered = @thunk_lowering.lower(ast) assert_no_custom_types(lowered, source_path) layout = Layout.new renderer = StatementRenderer.for_tree(lowered) emit_statements(statements_of(lowered), layout, renderer) layout.to_source end |