Class: SCSSLint::Linter

Inherits:
Sass::Tree::Visitors::Base
  • Object
show all
Includes:
SelectorVisitor, Utils
Defined in:
lib/scss_lint/linter.rb

Overview

Defines common functionality available to all linters.

Defined Under Namespace

Classes: BorderZero, CapitalizationInSelector, ColorKeyword, Comment, Compass, DebugStatement, DeclarationOrder, DuplicateProperty, EmptyLineBetweenBlocks, EmptyRule, FinalNewline, HexFormat, IdWithExtraneousSelector, Indentation, LeadingZero, NameFormat, PlaceholderInExtend, PropertySortOrder, PropertySpelling, SelectorDepth, Shorthand, SingleLinePerSelector, SpaceAfterComma, SpaceAfterPropertyColon, SpaceAfterPropertyName, SpaceBeforeBrace, SpaceBetweenParens, StringQuotes, TrailingSemicolonAfterPropertyValue, UrlFormat, UrlQuotes, ZeroUnit

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Utils

#can_be_condensed?, #extract_string_selectors, #pluralize, #previous_node, #remove_quoted_strings, #shortest_hex_form

Methods included from SelectorVisitor

#visit_selector

Constructor Details

#initializeLinter



9
10
11
# File 'lib/scss_lint/linter.rb', line 9

def initialize
  @lints = []
end

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config



7
8
9
# File 'lib/scss_lint/linter.rb', line 7

def config
  @config
end

#engineObject (readonly)

Returns the value of attribute engine



7
8
9
# File 'lib/scss_lint/linter.rb', line 7

def engine
  @engine
end

#lintsObject (readonly)

Returns the value of attribute lints



7
8
9
# File 'lib/scss_lint/linter.rb', line 7

def lints
  @lints
end

Instance Method Details

#add_lint(node_or_line, message) ⇒ Object

Helper for creating lint from a parse tree node



25
26
27
28
29
30
31
# File 'lib/scss_lint/linter.rb', line 25

def add_lint(node_or_line, message)
  line = node_or_line.respond_to?(:line) ? node_or_line.line : node_or_line

  @lints << Lint.new(engine.filename,
                     line,
                     message)
end

#character_at(source_position, offset = 0) ⇒ String



36
37
38
39
40
41
# File 'lib/scss_lint/linter.rb', line 36

def character_at(source_position, offset = 0)
  actual_line   = source_position.line - 1
  actual_offset = source_position.offset + offset - 1

  engine.lines[actual_line][actual_offset]
end

#node_on_single_line(node) ⇒ true, false

Returns whether a given node spans only a single line.



75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/scss_lint/linter.rb', line 75

def node_on_single_line(node)
  return if node.source_range.start_pos.line != node.source_range.end_pos.line

  # The Sass parser reports an incorrect source range if the trailing curly
  # brace is on the next line, e.g.
  #
  #   p {
  #   }
  #
  # Since we don't want to count this as a single line node, check if the
  # last character on the first line is an opening curly brace.
  engine.lines[node.line - 1].strip[-1] != '{'
end

#run(engine, config) ⇒ Object



15
16
17
18
19
# File 'lib/scss_lint/linter.rb', line 15

def run(engine, config)
  @config = config
  @engine = engine
  visit(engine.tree)
end

#source_from_range(source_range) ⇒ String

Extracts the original source code given a range.



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/scss_lint/linter.rb', line 47

def source_from_range(source_range)
  current_line = source_range.start_pos.line - 1
  last_line    = source_range.end_pos.line - 1
  start_pos    = source_range.start_pos.offset - 1

  if current_line == last_line
    source = engine.lines[current_line][start_pos..(source_range.end_pos.offset - 1)]
  else
    source = engine.lines[current_line][start_pos..-1]
  end

  current_line += 1
  while current_line < last_line
    source += "#{engine.lines[current_line]}"
    current_line += 1
  end

  if source_range.start_pos.line != source_range.end_pos.line
    source += "#{(engine.lines[current_line] || '')[0...source_range.end_pos.offset]}"
  end

  source
end

#visit(node) ⇒ Object

Modified so we can also visit selectors in linters



93
94
95
96
97
98
99
100
# File 'lib/scss_lint/linter.rb', line 93

def visit(node)
  # Visit the selector of a rule if parsed rules are available
  if node.is_a?(Sass::Tree::RuleNode) && node.parsed_rules
    visit_selector(node.parsed_rules)
  end

  super
end

#visit_children(parent) ⇒ Object

Redefine so we can set the `node_parent` of each node



106
107
108
109
110
111
# File 'lib/scss_lint/linter.rb', line 106

def visit_children(parent)
  parent.children.each do |child|
    child.node_parent = parent
    visit(child)
  end
end