class HamlLint::Tree::Node

Decorator class that provides a convenient set of helpers for HAML's {Haml::Parser::ParseNode} struct.

The goal is to abstract away the details of the underlying struct and provide a cleaner and more uniform interface for getting information about a node, as there are a number of weird/special cases in the struct returned by the HAML parser.

@abstract

Attributes

children[RW]
line[R]
parent[RW]
type[R]

Public Class Methods

new(document, parse_node) click to toggle source

Creates a node wrapping the given {Haml::Parser::ParseNode} struct.

@param document [HamlLint::Document] Haml document that created this node @param parse_node [Haml::Parser::ParseNode] parse node created by HAML's parser

# File lib/haml_lint/tree/node.rb, line 24
def initialize(document, parse_node)
  @line = parse_node.line
  @document = document
  @value = parse_node.value
  @type = parse_node.type
end

Public Instance Methods

comment_configuration() click to toggle source

Holds any configuration that is created from Haml comments.

@return [HamlLint::CommentConfiguration]

# File lib/haml_lint/tree/node.rb, line 34
def comment_configuration
  @comment_configuration ||= HamlLint::CommentConfiguration.new(self)
end
directives() click to toggle source

The comment directives to apply to the node.

@return [Array<HamlLint::Directive>]

# File lib/haml_lint/tree/node.rb, line 63
def directives
  directives = []
  directives << predecessor.directives if predecessor
  directives.flatten
end
disabled?(visitor) click to toggle source

Checks whether a visitor is disabled due to comment configuration.

@param [HamlLint::HamlVisitor] @return [true, false]

# File lib/haml_lint/tree/node.rb, line 42
def disabled?(visitor)
  visitor.is_a?(HamlLint::Linter) &&
    comment_configuration.disabled?(visitor.name)
end
each() { |node| ... } click to toggle source

Implements the Enumerable interface to walk through an entire tree.

@return [Enumerator, HamlLint::Tree::Node]

# File lib/haml_lint/tree/node.rb, line 50
def each
  return to_enum(__callee__) unless block_given?

  node = self
  loop do
    yield node
    break unless (node = node.next_node)
  end
end
inspect() click to toggle source
# File lib/haml_lint/tree/node.rb, line 85
def inspect
  "#<#{self.class.name}>"
end
line_numbers() click to toggle source

The line numbers that are contained within the node.

@api public @return [Range]

# File lib/haml_lint/tree/node.rb, line 103
def line_numbers
  return (line..line) unless @value && text

  end_line = line + lines.count
  end_line = nontrivial_end_line if line == end_line && children.empty?

  (line..end_line)
end
lines() click to toggle source

The lines of text, if any, that are contained in the node.

@api public @return [Array<String>]

# File lib/haml_lint/tree/node.rb, line 93
def lines
  return [] unless @value && text

  text.split(/\r\n|\r|\n/)
end
next_node() click to toggle source

Returns the next node that appears after this node in the document.

Returns nil if there is no next node.

@return [HamlLint::Tree::Node,nil]

# File lib/haml_lint/tree/node.rb, line 139
def next_node
  children.first || successor
end
predecessor() click to toggle source

The previous node to be traversed in the tree.

@return [HamlLint::Tree::Node, nil]

# File lib/haml_lint/tree/node.rb, line 115
def predecessor
  siblings.previous(self) || parent
end
source_code() click to toggle source

Source code of all lines this node spans (excluding children).

@return [String]

# File lib/haml_lint/tree/node.rb, line 72
def source_code
  next_node_line =
    if next_node
      next_node.line - 1
    else
      @document.source_lines.count + 1
    end

  @document.source_lines[@line - 1...next_node_line]
           .join("\n")
           .gsub(/^\s*\z/m, '') # Remove blank lines at the end
end
subsequents() click to toggle source

The sibling nodes that come after this node in the tree.

@return [Array<HamlLint::Tree::Node>]

# File lib/haml_lint/tree/node.rb, line 146
def subsequents
  siblings.subsequents(self)
end
successor() click to toggle source

Returns the node that follows this node, whether it be a sibling or an ancestor's child, but not a child of this node.

If you are also willing to return the child, call {#next_node}.

Returns nil if there is no successor.

@return [HamlLint::Tree::Node,nil]

# File lib/haml_lint/tree/node.rb, line 127
def successor
  next_sibling = siblings.next(self)
  return next_sibling if next_sibling

  parent&.successor
end
text() click to toggle source

Returns the text content of this node.

@return [String]

# File lib/haml_lint/tree/node.rb, line 153
def text
  @value[:text].to_s
end

Private Instance Methods

nontrivial_end_line() click to toggle source

Discovers the end line of the node when there are no lines.

@return [Integer] the end line of the node

# File lib/haml_lint/tree/node.rb, line 162
def nontrivial_end_line
  if successor
    successor.line_numbers.begin - 1
  else
    @document.source_lines.count
  end
end
siblings() click to toggle source

The siblings of this node within the tree.

@api private @return [Array<HamlLint::Tree::Node>]

# File lib/haml_lint/tree/node.rb, line 174
def siblings
  @siblings ||= Siblings.new(parent ? parent.children : [self])
end