module SlimLint::SexpVisitor

Provides an interface which when included allows a class to visit nodes in the Sexp of a Slim document.

Constants

SexpPattern

Mapping of Sexp pattern to callback method name.

@attr_reader sexp [Array] S-expression pattern that when matched triggers the

callback

@attr_reader callback_method_name [Symbol] name of the method to call when pattern is matched

Public Instance Methods

captures() click to toggle source

Returns the map of capture names to captured values.

@return [Hash, CaptureMap]

# File lib/slim_lint/sexp_visitor.rb, line 49
def captures
  self.class.captures || {}
end
on_start(*) click to toggle source

Executed before searching for any pattern matches.

@param sexp [SlimLint::Sexp] see {SexpVisitor::DSL.on_start} @return [Symbol] see {SexpVisitor::DSL.on_start}

# File lib/slim_lint/sexp_visitor.rb, line 64
def on_start(*)
  # Overidden by DSL.on_start
end
patterns() click to toggle source

Returns the list of registered Sexp patterns.

@return [Array<SlimLint::SexpVisitor::SexpPattern>]

# File lib/slim_lint/sexp_visitor.rb, line 56
def patterns
  self.class.patterns || []
end
traverse(sexp) click to toggle source

Traverse the given Sexp, firing callbacks if they are defined.

@param sexp [SlimLint::Sexp]

# File lib/slim_lint/sexp_visitor.rb, line 20
def traverse(sexp)
  patterns.each do |pattern|
    next unless sexp.match?(pattern.sexp)

    result = method(pattern.callback_method_name).call(sexp)

    # Returning :stop indicates we should stop searching this Sexp
    # (i.e. stop descending this branch of depth-first search).
    # The `return` here is very intentional.
    return if result == :stop # rubocop:disable Lint/NonLocalExitFromIterator
  end

  # Continue traversing children by default (match blocks can return `:stop`
  # to not continue).
  traverse_children(sexp)
end
traverse_children(sexp) click to toggle source

Traverse the children of this {Sexp}.

@param sexp [SlimLint::Sexp]

# File lib/slim_lint/sexp_visitor.rb, line 40
def traverse_children(sexp)
  sexp.each do |nested_sexp|
    traverse nested_sexp if nested_sexp.is_a?(Sexp)
  end
end
trigger_pattern_callbacks(sexp) click to toggle source

Traverse the Sexp looking for matches with registered patterns, firing callbacks for all matches.

@param sexp [SlimLint::Sexp]

# File lib/slim_lint/sexp_visitor.rb, line 11
def trigger_pattern_callbacks(sexp)
  return if on_start(sexp) == :stop

  traverse sexp
end