class Prism::ParseResult::Newlines
The :line tracepoint event gets fired whenever the Ruby VM encounters an expression on a new line. The types of expressions that can trigger this event are:
-
if statements
-
unless statements
-
nodes that are children of statements lists
In order to keep track of the newlines, we have a list of offsets that come back from the parser. We assign these offsets to the first nodes that we find in the tree that are on those lines.
Note that the logic in this file should be kept in sync with the Java MarkNewlinesVisitor, since that visitor is responsible for marking the newlines for JRuby/TruffleRuby.
This file is autoloaded only when mark_newlines! is called, so the re-opening of the various nodes in this file will only be performed in that case. We do that to avoid storing the extra @newline instance variable on every node if we donβt need it.
Public Class Methods
(Integer lines) → void
Source
# File lib/prism/parse_result/newlines.rb, line 36 def initialize(lines) @lines = Array.new(1 + lines, false) end
Create a new Newlines visitor with the given newline offsets.
Public Instance Methods
(BlockNode node) → void
Source
# File lib/prism/parse_result/newlines.rb, line 43 def visit_block_node(node) old_lines = @lines @lines = Array.new(old_lines.size, false) begin super(node) ensure @lines = old_lines end end
Permit block nodes to mark newlines within themselves.
(ClassNode node) → void
Source
# File lib/prism/parse_result/newlines.rb, line 88 def visit_class_node(node) old_lines = @lines @lines = Array.new(old_lines.size, false) begin super(node) ensure @lines = old_lines end end
Permit class nodes to mark newlines within themselves.
(DefNode node) → void
Source
# File lib/prism/parse_result/newlines.rb, line 74 def visit_def_node(node) old_lines = @lines @lines = Array.new(old_lines.size, !node.equal_loc.nil?) begin super(node) ensure @lines = old_lines end end
Permit def nodes to mark newlines within themselves. The body of an endless method definition never emits newline events, so in that case mark every line as already seen while visiting it instead. Nested scopes (blocks, lambdas, etc.) reset the lines and emit events again.
(EmbeddedStatementsNode node) → void
Source
# File lib/prism/parse_result/newlines.rb, line 132 def visit_embedded_statements_node(node) old_lines = @lines @lines = Array.new(old_lines.size, true) begin super(node) ensure @lines = old_lines end end
Statements inside string interpolation do not emit newline events, so mark every line as already seen while visiting them. Nested scopes (blocks, lambdas, defs, etc.) reset the lines and emit events again.
(IfNode node) → void
Source
# File lib/prism/parse_result/newlines.rb, line 182 def visit_if_node(node) node.newline_flag!(@lines) super(node) end
Mark if nodes as newlines.
(LambdaNode node) → void
Source
# File lib/prism/parse_result/newlines.rb, line 57 def visit_lambda_node(node) old_lines = @lines @lines = Array.new(old_lines.size, false) begin super(node) ensure @lines = old_lines end end
Permit lambda nodes to mark newlines within themselves.
(ModuleNode node) → void
Source
# File lib/prism/parse_result/newlines.rb, line 102 def visit_module_node(node) old_lines = @lines @lines = Array.new(old_lines.size, false) begin super(node) ensure @lines = old_lines end end
Permit module nodes to mark newlines within themselves.
(SingletonClassNode node) → void
Source
# File lib/prism/parse_result/newlines.rb, line 116 def visit_singleton_class_node(node) old_lines = @lines @lines = Array.new(old_lines.size, false) begin super(node) ensure @lines = old_lines end end
Permit singleton class nodes to mark newlines within themselves.
(StatementsNode node) → void
Source
# File lib/prism/parse_result/newlines.rb, line 198 def visit_statements_node(node) node.body.each do |child| child.newline_flag!(@lines) end super(node) end
Permit statements lists to mark newlines within themselves.
(UnlessNode node) → void
Source
# File lib/prism/parse_result/newlines.rb, line 190 def visit_unless_node(node) node.newline_flag!(@lines) super(node) end
Mark unless nodes as newlines.
(UntilNode node) → void
Source
# File lib/prism/parse_result/newlines.rb, line 166 def visit_until_node(node) old_lines = @lines @lines = Array.new(old_lines.size, false) begin visit(node.predicate) ensure @lines = old_lines end visit(node.statements) end
The predicate of an until loop is compiled at the end of the loop, after the body, so any statements it contains (from parentheses) emit their line events again even if the lines were already seen.
(WhileNode node) → void
Source
# File lib/prism/parse_result/newlines.rb, line 148 def visit_while_node(node) old_lines = @lines @lines = Array.new(old_lines.size, false) begin visit(node.predicate) ensure @lines = old_lines end visit(node.statements) end
The predicate of a while loop is compiled at the end of the loop, after the body, so any statements it contains (from parentheses) emit their line events again even if the lines were already seen.