Class: Fir::Indent

Inherits:
Object
  • Object
show all
Defined in:
lib/fir/indent.rb

Defined Under Namespace

Classes: IndentBlock, Position, Token

Constant Summary collapse

OPEN_TOKENS =
%w[if while for until unless def class module begin].freeze
OPTIONAL_DO_TOKENS =
%w[for while until].freeze
WHEN_MIDWAY_TOKEN =
%w[else when].freeze
IF_MIDWAY_TOKEN =
%w[else elsif].freeze
BEGIN_MIDWAY_TOKEN =
%w[rescue ensure else].freeze
BEGIN_IMPLICIT_TOKEN =
%w[rescue ensure].freeze
OPEN_HEREDOC_TOKEN =
%w[<<- <<~].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(lines) ⇒ Indent

Returns a new instance of Indent.



15
16
17
18
19
20
21
22
# File 'lib/fir/indent.rb', line 15

def initialize(lines)
  @lines = lines
  @stack = []
  @delimiter_stack = []
  @array_stack = []
  @paren_stack = []
  @heredoc_stack = []
end

Instance Attribute Details

#array_stackObject (readonly)

Returns the value of attribute array_stack.



11
12
13
# File 'lib/fir/indent.rb', line 11

def array_stack
  @array_stack
end

#delimiter_stackObject (readonly)

Returns the value of attribute delimiter_stack.



10
11
12
# File 'lib/fir/indent.rb', line 10

def delimiter_stack
  @delimiter_stack
end

#heredoc_stackObject (readonly)

Returns the value of attribute heredoc_stack.



13
14
15
# File 'lib/fir/indent.rb', line 13

def heredoc_stack
  @heredoc_stack
end

#linesObject (readonly)

Returns the value of attribute lines.



8
9
10
# File 'lib/fir/indent.rb', line 8

def lines
  @lines
end

#paren_stackObject (readonly)

Returns the value of attribute paren_stack.



12
13
14
# File 'lib/fir/indent.rb', line 12

def paren_stack
  @paren_stack
end

#stackObject (readonly)

Returns the value of attribute stack.



9
10
11
# File 'lib/fir/indent.rb', line 9

def stack
  @stack
end

Instance Method Details

#generateObject



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/fir/indent.rb', line 32

def generate
  indents = lines.each.with_index.with_object([]) do |(line, line_index), deltas|
    delta = stack.length
    delta += array_stack.length if in_array?
    delta += paren_stack.length if in_paren?
    delta += heredoc_stack.length if in_heredoc?
    line.split(' ').each_with_index do |word, word_index|
      token = construct_token(word, word_index, line_index)
      if any_open?(token)
        stack.push(token)
      elsif any_midway?(token)
        delta -= 1
      elsif any_close?(token)
        delta -= 1
        stack.pop
      elsif string_open_token?(token)
        delimiter_stack.push(token)
      elsif string_close_token?(token)
        delimiter_stack.pop
      elsif open_array_token?(token)
        array_stack.push(token)
      elsif close_array_token?(token)
        delta -= 1 if array_stack.last.position.y != token.position.y
        array_stack.pop
      elsif open_paren_token?(token)
        paren_stack.push(token)
      elsif close_paren_token?(token)
        delta -= 1 if paren_stack.last.position.y != token.position.y
        paren_stack.pop
      elsif open_heredoc_token?(token)
        heredoc_stack.push(token)
      elsif close_heredoc_token?(token)
        delta -= 1 if heredoc_stack.last.position.y != token.position.y
        heredoc_stack.pop
      end
    end
    deltas << delta
  end
  IndentBlock.new(indents, executable?(indents, lines))
end