Class: RuboCop::AST::NodePattern::Compiler::SequenceSubcompiler

Inherits:
Subcompiler
  • Object
show all
Defined in:
lib/rubocop/ast/node_pattern/compiler/sequence_subcompiler.rb

Overview

Compiles terms within a sequence to code that evalues to true or false. Compilation of the nodes that can match only a single term is deferred to `NodePatternSubcompiler`; only nodes that can match multiple terms are compiled here. Assumes the given `var` is a `::RuboCop::AST::Node`

Doc on how this fits in the compiling process:

/docs/modules/ROOT/pages/node_pattern.adoc

rubocop:disable Metrics/ClassLength

Direct Known Subclasses

Debug::SequenceSubcompiler

Constant Summary collapse

DELTA =
1

Instance Attribute Summary collapse

Attributes inherited from Subcompiler

#compiler

Instance Method Summary collapse

Methods inherited from Subcompiler

#compile, inherited, method_added

Constructor Details

#initialize(compiler, sequence:, var:) ⇒ SequenceSubcompiler

Calls `compile_sequence`; the actual `compile` method will be used for the different terms of the sequence. The only case of re-entrant call to `compile` is `visit_capture`


25
26
27
28
29
# File 'lib/rubocop/ast/node_pattern/compiler/sequence_subcompiler.rb', line 25

def initialize(compiler, sequence:, var:)
  @seq = sequence # The node to be compiled
  @seq_var = var  # Holds the name of the variable holding the AST::Node we are matching
  super(compiler)
end

Instance Attribute Details

#in_syncObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.


251
252
253
# File 'lib/rubocop/ast/node_pattern/compiler/sequence_subcompiler.rb', line 251

def in_sync
  @in_sync
end

Instance Method Details

#compile_sequenceObject


31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/rubocop/ast/node_pattern/compiler/sequence_subcompiler.rb', line 31

def compile_sequence
  # rubocop:disable Layout/CommentIndentation
  compiler.with_temp_variables do |cur_child, cur_index, previous_index|
    @cur_child_var = cur_child        # To hold the current child node
    @cur_index_var = cur_index        # To hold the current child index (always >= 0)
    @prev_index_var = previous_index  # To hold the child index before we enter the
                                      # variadic nodes
    @cur_index = :seq_head            # Can be any of:
                                      # :seq_head : when the current child is actually the
                                      #             sequence head
                                      # :variadic_mode : child index held by @cur_index_var
                                      # >= 0 : when the current child index is known
                                      #        (from the beginning)
                                      # < 0 :  when the index is known from the end,
                                      #        where -1 is *past the end*,
                                      #        -2 is the last child, etc...
                                      #        This shift of 1 from standard Ruby indices
                                      #        is stored in DELTA
    @in_sync = false                  # `true` iff `@cur_child_var` and `@cur_index_var`
                                      # correspond to `@cur_index`
                                      # Must be true if `@cur_index` is `:variadic_mode`
    compile_terms
  end
  # rubocop:enable Layout/CommentIndentation
end