Class: SlimLint::Sexp

Inherits:
Array
  • Object
show all
Defined in:
lib/slim_lint/sexp.rb

Overview

Symbolic expression which represents tree-structured data.

The main use of this particular implementation is to provide a single location for defining convenience helpers when operating on Sexps.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(array_sexp) ⇒ Sexp

Creates an SlimLint::Sexp from the given Array-based Sexp.

This provides a convenient way to convert between literal arrays of Symbols and SlimLint::Sexps containing Atoms and nested SlimLint::Sexps. These objects all expose a similar API that conveniently allows the two objects to be treated similarly due to duck typing.

Parameters:

  • array_sexp (Array)


21
22
23
24
25
26
27
28
29
30
# File 'lib/slim_lint/sexp.rb', line 21

def initialize(array_sexp)
  array_sexp.each do |atom_or_sexp|
    case atom_or_sexp
    when Array
      push Sexp.new(atom_or_sexp)
    else
      push SlimLint::Atom.new(atom_or_sexp)
    end
  end
end

Instance Attribute Details

#lineObject

Stores the line number of the code in the original document that corresponds to this Sexp.



11
12
13
# File 'lib/slim_lint/sexp.rb', line 11

def line
  @line
end

Instance Method Details

#inspectString

Returns pretty-printed representation of this S-expression.

Returns:

  • (String)


71
72
73
# File 'lib/slim_lint/sexp.rb', line 71

def inspect
  display
end

#match?(sexp_pattern) ⇒ Boolean

Returns whether this SlimLint::Sexp matches the given Sexp pattern.

A Sexp pattern is simply an incomplete Sexp prefix.

Note that nested Sexps will also be matched, so be careful about the cost of matching against a complicated pattern.

Examples:

The following Sexp:

  [:html, :doctype, "html5"]

...will match the given patterns:

  [:html]
  [:html, :doctype]
  [:html, :doctype, "html5"]

Parameters:

  • sexp_pattern (Object, Array)

Returns:

  • (Boolean)


52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/slim_lint/sexp.rb', line 52

def match?(sexp_pattern)
  # Delegate matching logic if we're comparing against a matcher
  if sexp_pattern.is_a?(SlimLint::Matcher::Base)
    return sexp_pattern.match?(self)
  end

  # If there aren't enough items to compare then this obviously won't match
  return false unless sexp_pattern.is_a?(Array) && length >= sexp_pattern.length

  sexp_pattern.each_with_index do |sub_pattern, index|
    return false unless self[index].match?(sub_pattern)
  end

  true
end