Class: IRB::NestingParser::NestingVisitor
| Relationships & Source Files | |
| Super Chains via Extension / Inclusion / Inheritance | |
|
Class Chain:
self,
Prism::Visitor
|
|
|
Instance Chain:
self,
Prism::Visitor
|
|
| Inherits: |
Prism::Visitor
|
| Defined in: | lib/irb/nesting_parser.rb |
Class Method Summary
- .new ⇒ NestingVisitor constructor
Instance Method Summary
- #close(line, column)
- #close_closing_loc(node)
- #close_end_keyword_loc(node)
- #close_location(location)
- #close_location_start(location)
- #heredoc_open(node)
- #heredoc_string_like(node, type)
-
#modifier_node?(node, keyword_loc) ⇒ Boolean
Checks if a node (if, while, etc) is a modifier form that does not need
endclosing. - #nestings
- #open(line, column, elem)
- #open_location(location, type, tok)
- #visit_array_node(node)
- #visit_begin_node(node)
- #visit_block_node(node)
- #visit_block_parameters_node(node)
- #visit_call_node(node)
-
#visit_case_match_node(node)
Alias for #visit_case_node.
- #visit_case_node(node) (also: #visit_case_match_node)
- #visit_class_node(node) (also: #visit_singleton_class_node)
- #visit_def_node(node)
-
#visit_defined_node(node)
Alias for #visit_super_node.
- #visit_else_node(node)
- #visit_embedded_statements_node(node)
- #visit_ensure_node(node)
- #visit_for_node(node)
- #visit_hash_node(node)
- #visit_if_node(node)
- #visit_in_node(node)
-
#visit_interpolated_regular_expression_node(node)
Alias for #visit_regular_expression_node.
- #visit_interpolated_string_node(node) (also: #visit_string_node)
-
#visit_interpolated_symbol_node(node)
Alias for #visit_symbol_node.
- #visit_interpolated_x_string_node(node) (also: #visit_x_string_node)
- #visit_lambda_node(node)
- #visit_module_node(node)
- #visit_parentheses_node(node)
- #visit_regular_expression_node(node) (also: #visit_interpolated_regular_expression_node)
- #visit_rescue_node(node)
-
#visit_singleton_class_node(node)
Alias for #visit_class_node.
-
#visit_string_node(node)
Alias for #visit_interpolated_string_node.
- #visit_super_node(node) (also: #visit_yield_node, #visit_defined_node)
- #visit_symbol_node(node) (also: #visit_interpolated_symbol_node)
- #visit_unless_node(node)
- #visit_until_node(node)
- #visit_when_node(node)
- #visit_while_node(node)
-
#visit_x_string_node(node)
Alias for #visit_interpolated_x_string_node.
-
#visit_yield_node(node)
Alias for #visit_super_node.
Constructor Details
.new ⇒ NestingVisitor
# File 'lib/irb/nesting_parser.rb', line 10
def initialize # Array of [column, priority(+1/-1), NestingElem(open) or nil(close)] per line. # priority is +1 for open, -1 for close so that close comes before open when sorted. # Example: # if cond # else # end # `else` closes `if` at column 0 first and then opens `else` at column 0 next. @lines = [] # Array of open heredoc NestingElem per line @heredocs = [] end
Instance Method Details
#close(line, column)
[ GitHub ]# File 'lib/irb/nesting_parser.rb', line 51
def close(line, column) (@lines[line - 1] ||= []) << [column, -1] end
#close_closing_loc(node)
[ GitHub ]# File 'lib/irb/nesting_parser.rb', line 77
def close_closing_loc(node) close_location(node.closing_loc) if node.closing_loc && !node.closing.empty? end
#close_end_keyword_loc(node)
[ GitHub ]# File 'lib/irb/nesting_parser.rb', line 73
def close_end_keyword_loc(node) close_location(node.end_keyword_loc) if node.end_keyword == 'end' end
#close_location(location)
[ GitHub ]# File 'lib/irb/nesting_parser.rb', line 65
def close_location(location) close(location.end_line, location.end_column) end
#close_location_start(location)
[ GitHub ]# File 'lib/irb/nesting_parser.rb', line 69
def close_location_start(location) close(location.start_line, location.start_column) end
#heredoc_open(node)
[ GitHub ]# File 'lib/irb/nesting_parser.rb', line 42
def heredoc_open(node) elem = NestingElem.new([node.location.start_line, node.location.start_column], :on_heredoc_beg, node.opening) (@heredocs[node.location.start_line - 1] ||= []) << elem end
#heredoc_string_like(node, type)
[ GitHub ]# File 'lib/irb/nesting_parser.rb', line 219
def heredoc_string_like(node, type) if node.opening&.start_with?('<<') heredoc_open(node) # Heredoc closing contains trailing newline. We need to exclude it close_location_start(node.closing_loc) if node.closing_loc && !node.closing.empty? elsif node.opening open_location(node.location, type, node.opening) if node.closing && node.closing != '' # Closing of `"#{\n` is "\n". We need to treat it as not-closed. close_location_start(node.closing_loc) if node.opening.match?(/\n\z/) || node.closing != "\n" end end end
#modifier_node?(node, keyword_loc) ⇒ Boolean
Checks if a node (if, while, etc) is a modifier form that does not need end closing. modifier node: a if b, non-modifier node: if a; b; end
# File 'lib/irb/nesting_parser.rb', line 57
def modifier_node?(node, keyword_loc) !(keyword_loc && node.location.start_line == keyword_loc.start_line && node.location.start_column == keyword_loc.start_column) end
#nestings
[ GitHub ]# File 'lib/irb/nesting_parser.rb', line 24
def nestings size = [@lines.size, @heredocs.size].max nesting = [] size.times.map do |line_index| @lines[line_index]&.sort_by { |col, pri| [col, pri] }&.each do |col, pri, elem| if elem nesting << elem else nesting.pop end end @heredocs[line_index]&.sort_by { |elem| elem.pos[1] }&.reverse_each do |elem| nesting << elem end nesting.dup end end
#open(line, column, elem)
[ GitHub ]# File 'lib/irb/nesting_parser.rb', line 47
def open(line, column, elem) (@lines[line - 1] ||= []) << [column, +1, elem] end
#open_location(location, type, tok)
[ GitHub ]# File 'lib/irb/nesting_parser.rb', line 61
def open_location(location, type, tok) open(location.start_line, location.start_column, NestingElem.new([location.start_line, location.start_column], type, tok)) end
#visit_array_node(node)
[ GitHub ]# File 'lib/irb/nesting_parser.rb', line 188
def visit_array_node(node) super type = case node.opening when nil # `x = 1, 2` doesn't have opening nil when '[' :bracket when /\A%W/ :on_words_beg when /\A%w/ :on_qwords_beg when /\A%I/ :on_symbols_beg when /\A%i/ :on_qsymbols_beg end if type open_location(node.location, type, node.opening) close_closing_loc(node) end end
#visit_begin_node(node)
[ GitHub ]# File 'lib/irb/nesting_parser.rb', line 174
def visit_begin_node(node) super if node.begin_keyword open_location(node.location, :on_kw, 'begin') close_end_keyword_loc(node) end end
#visit_block_node(node)
[ GitHub ]# File 'lib/irb/nesting_parser.rb', line 182
def visit_block_node(node) super open_location(node.location, node.opening == '{' ? :on_lbrace : :on_kw, node.opening) close_closing_loc(node) end
#visit_block_parameters_node(node)
[ GitHub ]# File 'lib/irb/nesting_parser.rb', line 290
def visit_block_parameters_node(node) super if node.opening == '(' open_location(node.location, :on_lparen, '(') close_closing_loc(node) end end
#visit_call_node(node)
[ GitHub ]# File 'lib/irb/nesting_parser.rb', line 274
def visit_call_node(node) super type = case node.opening when '(' :on_lparen when '[' :on_lbracket end if type open_location(node.opening_loc, type, node.opening) close_closing_loc(node) end end
#visit_case_match_node(node)
Alias for #visit_case_node.
# File 'lib/irb/nesting_parser.rb', line 136
alias visit_case_match_node visit_case_node
#visit_case_node(node) Also known as: #visit_case_match_node
[ GitHub ]# File 'lib/irb/nesting_parser.rb', line 127
def visit_case_node(node) super open_location(node.location, :on_kw, 'case') if node.else_clause close_location_start(node.else_clause.location) else close_end_keyword_loc(node) end end
#visit_class_node(node) Also known as: #visit_singleton_class_node
[ GitHub ]# File 'lib/irb/nesting_parser.rb', line 328
def visit_class_node(node) super open_location(node.location, :on_kw, 'class') close_end_keyword_loc(node) end
#visit_def_node(node)
[ GitHub ]# File 'lib/irb/nesting_parser.rb', line 314
def visit_def_node(node) super open_location(node.location, :on_kw, 'def') if node.lparen == '(' open_location(node.lparen_loc, :on_lparen, '(') close_location(node.rparen_loc) if node.rparen == ')' end if node.equal close_location(node.equal_loc) else close_end_keyword_loc(node) end end
#visit_defined_node(node)
Alias for #visit_super_node.
# File 'lib/irb/nesting_parser.rb', line 312
alias visit_defined_node visit_super_node
#visit_else_node(node)
[ GitHub ]# File 'lib/irb/nesting_parser.rb', line 150
def visit_else_node(node) super if node.else_keyword == 'else' open_location(node.location, :on_kw, 'else') close_end_keyword_loc(node) end end
#visit_embedded_statements_node(node)
[ GitHub ]# File 'lib/irb/nesting_parser.rb', line 233
def (node) super open_location(node.location, :on_embexpr_beg, '#{') close_closing_loc(node) end
#visit_ensure_node(node)
[ GitHub ]# File 'lib/irb/nesting_parser.rb', line 158
def visit_ensure_node(node) super return if modifier_node?(node, node.ensure_keyword_loc) close_location_start(node.location) open_location(node.location, :on_kw, 'ensure') end
#visit_for_node(node)
[ GitHub ]# File 'lib/irb/nesting_parser.rb', line 81
def visit_for_node(node) super open_location(node.location, :on_kw, 'for') close_end_keyword_loc(node) end
#visit_hash_node(node)
[ GitHub ]# File 'lib/irb/nesting_parser.rb', line 213
def visit_hash_node(node) super open_location(node.location, :on_lbrace, '{') close_closing_loc(node) end
#visit_if_node(node)
[ GitHub ]# File 'lib/irb/nesting_parser.rb', line 103
def visit_if_node(node) super return if !node.if_keyword || modifier_node?(node, node.if_keyword_loc) open_location(node.location, :on_kw, node.if_keyword) if node.subsequent close_location_start(node.subsequent.location) else close_end_keyword_loc(node) end end
#visit_in_node(node)
[ GitHub ]# File 'lib/irb/nesting_parser.rb', line 144
def visit_in_node(node) super close_location_start(node.location) open_location(node.location, :on_kw, 'in') end
#visit_interpolated_regular_expression_node(node)
Alias for #visit_regular_expression_node.
# File 'lib/irb/nesting_parser.rb', line 266
alias visit_interpolated_regular_expression_node visit_regular_expression_node
#visit_interpolated_string_node(node) Also known as: #visit_string_node
[ GitHub ]# File 'lib/irb/nesting_parser.rb', line 239
def visit_interpolated_string_node(node) super heredoc_string_like(node, :on_tstring_beg) end
#visit_interpolated_symbol_node(node)
Alias for #visit_symbol_node.
# File 'lib/irb/nesting_parser.rb', line 259
alias visit_interpolated_symbol_node visit_symbol_node
#visit_interpolated_x_string_node(node) Also known as: #visit_x_string_node
[ GitHub ]# File 'lib/irb/nesting_parser.rb', line 245
def visit_interpolated_x_string_node(node) super heredoc_string_like(node, :on_backtick) end
#visit_lambda_node(node)
[ GitHub ]# File 'lib/irb/nesting_parser.rb', line 298
def visit_lambda_node(node) super open_location(node.opening_loc, :on_tlambeg, node.opening) close_closing_loc(node) end
#visit_module_node(node)
[ GitHub ]# File 'lib/irb/nesting_parser.rb', line 335
def visit_module_node(node) super open_location(node.location, :on_kw, 'module') close_end_keyword_loc(node) end
#visit_parentheses_node(node)
[ GitHub ]# File 'lib/irb/nesting_parser.rb', line 268
def visit_parentheses_node(node) super open_location(node.location, :on_lparen, '(') close_closing_loc(node) end
#visit_regular_expression_node(node) Also known as: #visit_interpolated_regular_expression_node
[ GitHub ]# File 'lib/irb/nesting_parser.rb', line 261
def visit_regular_expression_node(node) super open_location(node.location, :on_regexp_beg, node.opening) close_closing_loc(node) end
#visit_rescue_node(node)
[ GitHub ]# File 'lib/irb/nesting_parser.rb', line 166
def visit_rescue_node(node) super return if modifier_node?(node, node.keyword_loc) close_location_start(node.location) open_location(node.location, :on_kw, 'rescue') end
#visit_singleton_class_node(node)
Alias for #visit_class_node.
# File 'lib/irb/nesting_parser.rb', line 333
alias visit_singleton_class_node visit_class_node
#visit_string_node(node)
Alias for #visit_interpolated_string_node.
# File 'lib/irb/nesting_parser.rb', line 243
alias visit_string_node visit_interpolated_string_node
#visit_super_node(node) Also known as: #visit_yield_node, #visit_defined_node
[ GitHub ]# File 'lib/irb/nesting_parser.rb', line 304
def visit_super_node(node) super if node.lparen open_location(node.lparen_loc, :on_lparen, '(') close_location(node.rparen_loc) if node.rparen == ')' end end
#visit_symbol_node(node) Also known as: #visit_interpolated_symbol_node
[ GitHub ]# File 'lib/irb/nesting_parser.rb', line 251
def visit_symbol_node(node) super unless node.opening.nil? || node.opening.empty? || node.opening == ':' # :"sym" or %s[sym] open_location(node.location, :on_symbeg, node.opening) close_closing_loc(node) end end
#visit_unless_node(node)
[ GitHub ]# File 'lib/irb/nesting_parser.rb', line 115
def visit_unless_node(node) super return if modifier_node?(node, node.keyword_loc) open_location(node.location, :on_kw, 'unless') if node.else_clause close_location_start(node.else_clause.location) else close_end_keyword_loc(node) end end
#visit_until_node(node)
[ GitHub ]# File 'lib/irb/nesting_parser.rb', line 95
def visit_until_node(node) super return if modifier_node?(node, node.keyword_loc) open_location(node.location, :on_kw, 'until') close_closing_loc(node) end
#visit_when_node(node)
[ GitHub ]# File 'lib/irb/nesting_parser.rb', line 138
def visit_when_node(node) super close_location_start(node.location) open_location(node.location, :on_kw, 'when') end
#visit_while_node(node)
[ GitHub ]# File 'lib/irb/nesting_parser.rb', line 87
def visit_while_node(node) super return if modifier_node?(node, node.keyword_loc) open_location(node.location, :on_kw, 'while') close_closing_loc(node) end
#visit_x_string_node(node)
Alias for #visit_interpolated_x_string_node.
# File 'lib/irb/nesting_parser.rb', line 249
alias visit_x_string_node visit_interpolated_x_string_node
#visit_yield_node(node)
Alias for #visit_super_node.
# File 'lib/irb/nesting_parser.rb', line 311
alias visit_yield_node visit_super_node