Class: DeadEnd::CodeBlock

Inherits:
Object
  • Object
show all
Defined in:
lib/dead_end/code_block.rb

Overview

Multiple lines form a singular CodeBlock

Source code is made of multiple CodeBlocks.

Example:

code_block.to_s # =>
  #   def foo
  #     puts "foo"
  #   end

code_block.valid? # => true
code_block.in_valid? # => false

Constant Summary collapse

UNSET =
Object.new.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(lines: []) ⇒ CodeBlock

Returns a new instance of CodeBlock.



23
24
25
26
27
28
29
# File 'lib/dead_end/code_block.rb', line 23

def initialize(lines: [])
  @lines = Array(lines)
  @valid = UNSET
  @deleted = false
  @starts_at = @lines.first.number
  @ends_at = @lines.last.number
end

Instance Attribute Details

#ends_atObject (readonly)

Returns the value of attribute ends_at.



21
22
23
# File 'lib/dead_end/code_block.rb', line 21

def ends_at
  @ends_at
end

#linesObject (readonly)

Returns the value of attribute lines.



21
22
23
# File 'lib/dead_end/code_block.rb', line 21

def lines
  @lines
end

#starts_atObject (readonly)

Returns the value of attribute starts_at.



21
22
23
# File 'lib/dead_end/code_block.rb', line 21

def starts_at
  @starts_at
end

Instance Method Details

#<=>(other) ⇒ Object

This is used for frontier ordering, we are searching from the largest indentation to the smallest. This allows us to populate an array with multiple code blocks then call ‘sort!` on it without having to specify the sorting criteria



59
60
61
62
63
64
65
# File 'lib/dead_end/code_block.rb', line 59

def <=>(other)
  out = current_indent <=> other.current_indent
  return out if out != 0

  # Stable sort
  starts_at <=> other.starts_at
end

#current_indentObject



67
68
69
# File 'lib/dead_end/code_block.rb', line 67

def current_indent
  @current_indent ||= lines.select(&:not_empty?).map(&:indent).min || 0
end

#deleteObject



31
32
33
# File 'lib/dead_end/code_block.rb', line 31

def delete
  @deleted = true
end

#deleted?Boolean

Returns:

  • (Boolean)


35
36
37
# File 'lib/dead_end/code_block.rb', line 35

def deleted?
  @deleted
end

#hidden?Boolean

Returns:

  • (Boolean)


51
52
53
# File 'lib/dead_end/code_block.rb', line 51

def hidden?
  @lines.all?(&:hidden?)
end

#invalid?Boolean

Returns:

  • (Boolean)


71
72
73
# File 'lib/dead_end/code_block.rb', line 71

def invalid?
  !valid?
end

#is_end?Boolean

Returns:

  • (Boolean)


47
48
49
# File 'lib/dead_end/code_block.rb', line 47

def is_end?
  to_s.strip == "end"
end

#mark_invisibleObject



43
44
45
# File 'lib/dead_end/code_block.rb', line 43

def mark_invisible
  @lines.map(&:mark_invisible)
end

#to_sObject



96
97
98
# File 'lib/dead_end/code_block.rb', line 96

def to_s
  @lines.join
end

#valid?Boolean

Returns:

  • (Boolean)


75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/dead_end/code_block.rb', line 75

def valid?
  if @valid == UNSET
    # Performance optimization
    #
    # If all the lines were previously hidden
    # and we expand to capture additional empty
    # lines then the result cannot be invalid
    #
    # That means there's no reason to re-check all
    # lines with ripper (which is expensive).
    # Benchmark in commit message
    @valid = if lines.all? { |l| l.hidden? || l.empty? }
      true
    else
      DeadEnd.valid?(lines.map(&:original).join)
    end
  else
    @valid
  end
end

#visible_linesObject



39
40
41
# File 'lib/dead_end/code_block.rb', line 39

def visible_lines
  @lines.select(&:visible?).select(&:not_empty?)
end