class RuboCop::NodePattern::Compiler::Sequence
@private Builds Ruby code for a sequence (head *first_terms variadic_term *last_terms)
Public Class Methods
new(compiler, *arity_term_list)
click to toggle source
Calls superclass method
# File lib/rubocop/node_pattern.rb, line 309 def initialize(compiler, *arity_term_list) @arities, @terms = arity_term_list.transpose super(compiler) @variadic_index = @arities.find_index { |a| a.is_a?(Range) } fail_due_to 'multiple variable patterns in same sequence' \ if @variadic_index && !@arities.one? { |a| a.is_a?(Range) } end
Public Instance Methods
compile()
click to toggle source
# File lib/rubocop/node_pattern.rb, line 318 def compile [ compile_guard_clause, compile_child_nb_guard, compile_seq_head, *compile_first_terms, compile_variadic_term, *compile_last_terms ].compact.join(" &&\n") << SEQ_HEAD_GUARD end
Private Instance Methods
compile_child_nb_guard()
click to toggle source
# File lib/rubocop/node_pattern.rb, line 355 def compile_child_nb_guard fixed = first_terms_arity + last_terms_arity min = fixed + variadic_term_min_arity op = if @variadic_index max_variadic = @arities[@variadic_index].end if max_variadic != Float::INFINITY range = min..fixed + max_variadic return "(#{range}).cover?(#{CUR_NODE}.children.size)" end '>=' else '==' end "#{CUR_NODE}.children.size #{op} #{min}" end
compile_first_terms()
click to toggle source
# File lib/rubocop/node_pattern.rb, line 389 def compile_first_terms first_terms_range { |range| compile_terms(range, 0) } end
compile_last_terms()
click to toggle source
# File lib/rubocop/node_pattern.rb, line 393 def compile_last_terms last_terms_range { |r| compile_terms(r, -last_terms_arity) } end
compile_seq_head()
click to toggle source
# File lib/rubocop/node_pattern.rb, line 380 def compile_seq_head return unless seq_head? fail_due_to 'sequences can not start with <' \ if @terms[0].respond_to? :call with_seq_head_context(@terms[0]) end
compile_terms(index_range, start)
click to toggle source
# File lib/rubocop/node_pattern.rb, line 397 def compile_terms(index_range, start) index_range.map do |i| current = start start += @arities.fetch(i) term(i, current..start - 1) end end
compile_variadic_term()
click to toggle source
# File lib/rubocop/node_pattern.rb, line 405 def compile_variadic_term variadic_arity { |arity| term(@variadic_index, arity) } end
first_terms_arity()
click to toggle source
# File lib/rubocop/node_pattern.rb, line 331 def first_terms_arity first_terms_range { |r| @arities[r].inject(0, :+) } || 0 end
first_terms_range() { |1..(variadic_index || size) - 1| ... }
click to toggle source
# File lib/rubocop/node_pattern.rb, line 343 def first_terms_range yield 1..(@variadic_index || @terms.size) - 1 if seq_head? end
last_terms_arity()
click to toggle source
# File lib/rubocop/node_pattern.rb, line 335 def last_terms_arity last_terms_range { |r| @arities[r].inject(0, :+) } || 0 end
last_terms_range() { |variadic_index| ... }
click to toggle source
# File lib/rubocop/node_pattern.rb, line 347 def last_terms_range yield @variadic_index + 1...@terms.size if @variadic_index end
seq_head?()
click to toggle source
# File lib/rubocop/node_pattern.rb, line 351 def seq_head? @variadic_index != 0 end
term(index, range)
click to toggle source
# File lib/rubocop/node_pattern.rb, line 371 def term(index, range) t = @terms[index] if t.respond_to? :call t.call(range) else with_child_context(t, range.begin) end end
variadic_arity() { |first..-last_terms_arity - 1| ... }
click to toggle source
# File lib/rubocop/node_pattern.rb, line 409 def variadic_arity return unless @variadic_index first = @variadic_index.positive? ? first_terms_arity : SEQ_HEAD_INDEX yield first..-last_terms_arity - 1 end
variadic_term_min_arity()
click to toggle source
# File lib/rubocop/node_pattern.rb, line 339 def variadic_term_min_arity @variadic_index ? @arities[@variadic_index].begin : 0 end