Class: ASTTransform::StatementRenderer
- Inherits:
-
Object
- Object
- ASTTransform::StatementRenderer
- Defined in:
- lib/ast_transform/statement_renderer.rb
Overview
Renders individual statements to text via Unparser, working around the two consequences of unparsing them in isolation (line-aligned emission places each statement independently, so each is ripped out of its context):
- Isolation loses the surrounding scope's local variables, making Unparser re-parse identifiers as method calls and fail its dstr round-trip verification — so a renderer is built once per tree with every local bound anywhere in it, and feeds Unparser that set on each render.
- Unparser normalizes some single-line constructs into multi-line form, which would push following statements off their lines — so renders taller than their source are compressed back to one line when safely possible.
Immutable: configured with the tree's locals at construction, no per-render state.
Constant Summary collapse
- LOCAL_BINDING_TYPES =
Node types that bind a local variable name: assignments plus every method/block parameter flavor.
[:lvasgn, :arg, :optarg, :restarg, :kwarg, :kwoptarg, :blockarg, :shadowarg].freeze
Class Method Summary collapse
-
.for_tree(node) ⇒ Object
Builds a renderer for statements of +node+'s tree, holding every local bound anywhere in it — an over-approximation that is safe because the set only informs Unparser's re-parse verification, never the rendered text.
Instance Method Summary collapse
-
#aligned_render(node) ⇒ Object
Renders
nodeno taller than its source when safely possible. -
#initialize(local_variables:) ⇒ StatementRenderer
constructor
A new instance of StatementRenderer.
-
#unparse(node) ⇒ String
Unparser's render, informed of the tree's locals.
Constructor Details
#initialize(local_variables:) ⇒ StatementRenderer
Returns a new instance of StatementRenderer.
40 41 42 |
# File 'lib/ast_transform/statement_renderer.rb', line 40 def initialize(local_variables:) @local_variables = local_variables end |
Class Method Details
.for_tree(node) ⇒ Object
Builds a renderer for statements of +node+'s tree, holding every local bound anywhere in it — an over-approximation that is safe because the set only informs Unparser's re-parse verification, never the rendered text.
24 25 26 |
# File 'lib/ast_transform/statement_renderer.rb', line 24 def for_tree(node) new(local_variables: collect_local_variables(node)) end |
Instance Method Details
#aligned_render(node) ⇒ Object
Renders node no taller than its source when safely possible. Unparser normalizes some single-line
constructs into multi-line form (e.g. modifier-if into if/end); when the render is taller than the
statement's source, compress it back to one line — verified by re-parse so a statement that cannot be safely
single-lined (e.g. containing a heredoc) falls back to its multi-line render.
54 55 56 57 58 59 60 61 62 63 |
# File 'lib/ast_transform/statement_renderer.rb', line 54 def aligned_render(node) render = unparse(node) loc = node.loc return render unless loc.respond_to?(:last_line) && loc.line source_height = loc.last_line - loc.line + 1 return render if render.count("\n") < source_height compress_to_single_line(render) || render end |
#unparse(node) ⇒ String
Returns Unparser's render, informed of the tree's locals.
46 47 48 |
# File 'lib/ast_transform/statement_renderer.rb', line 46 def unparse(node) Unparser.unparse(node, static_local_variables: @local_variables) end |