Class: Epuber::Compiler::Problem

Inherits:
Object
  • Object
show all
Defined in:
lib/epuber/compiler/problem.rb

Defined Under Namespace

Classes: Location

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(level, message, source, location: nil, line: nil, column: nil, length: nil, file_path: nil) ⇒ Problem

Returns a new instance of Problem.



18
19
20
21
22
23
24
25
26
# File 'lib/epuber/compiler/problem.rb', line 18

def initialize(level, message, source, location: nil, line: nil, column: nil, length: nil, file_path: nil)
  @level = level
  @message = message
  @source = source
  @location = location
  @location = Location.new(line, column, length) if @location.nil? && line && column

  @file_path = file_path
end

Instance Attribute Details

#file_pathObject (readonly)

Returns the value of attribute file_path.



16
17
18
# File 'lib/epuber/compiler/problem.rb', line 16

def file_path
  @file_path
end

#levelObject (readonly)

Returns the value of attribute level.



16
17
18
# File 'lib/epuber/compiler/problem.rb', line 16

def level
  @level
end

#locationObject (readonly)

Returns the value of attribute location.



16
17
18
# File 'lib/epuber/compiler/problem.rb', line 16

def location
  @location
end

#messageObject (readonly)

Returns the value of attribute message.



16
17
18
# File 'lib/epuber/compiler/problem.rb', line 16

def message
  @message
end

#sourceObject (readonly)

Returns the value of attribute source.



16
17
18
# File 'lib/epuber/compiler/problem.rb', line 16

def source
  @source
end

Class Method Details

.caret_symbol(indent) ⇒ String

Formats caret symbol with space indent

Parameters:

  • indent (Fixnum)

Returns:

  • (String)


34
35
36
# File 'lib/epuber/compiler/problem.rb', line 34

def self.caret_symbol(indent)
  "#{' ' * indent}^"
end

.caret_symbols(indent, length) ⇒ String

Formats caret symbols for indent and length

Parameters:

  • length (Fixnum)
  • indent (Fixnum)

Returns:

  • (String)


45
46
47
48
49
50
51
52
53
54
# File 'lib/epuber/compiler/problem.rb', line 45

def self.caret_symbols(indent, length)
  start_sign = caret_symbol(indent)
  end_sign = if length > 1
               caret_symbol(length - 2)
             else
               ''
             end

  "#{start_sign}#{end_sign}"
end

.formatted_match_line(text, location) ⇒ Object



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/epuber/compiler/problem.rb', line 78

def self.formatted_match_line(text, location)
  pre, matched, post = text_at(text, location)

  pre_line = pre.split("\n").last || ''
  post_line = post.split("\n").first || ''

  pre = match_pre_line = pre_line
  pre = "#{match_pre_line.first(20)}...#{match_pre_line.last(30)}" if remove_tabs(match_pre_line).length > 100

  pre = remove_tabs(pre)

  post = if post_line.length > 50
           "#{post_line.first(50)}..."
         else
           post_line
         end

  [pre, matched, post]
end

.remove_tabs(text) ⇒ Object



56
57
58
# File 'lib/epuber/compiler/problem.rb', line 56

def self.remove_tabs(text)
  text.gsub("\t", ' ' * 4)
end

.text_at(text, location) ⇒ Object

Parameters:



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/epuber/compiler/problem.rb', line 62

def self.text_at(text, location)
  line_index = location.line - 1
  column_index = location.column - 1

  lines = text.split("\n")

  line = lines[line_index] || ''
  matched_text = line[column_index...column_index + location.length] || ''

  pre = (lines[0...line_index] + [line[0...column_index]]).join("\n")
  post = ([line[column_index + location.length..line.length]] + (lines[location.line..lines.count] || []))
         .join("\n")

  [pre, matched_text, post]
end

Instance Method Details

#to_sObject



98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/epuber/compiler/problem.rb', line 98

def to_s
  pre, match_text, post = self.class.formatted_match_line(@source, @location)

  pointers = self.class.caret_symbols(pre.length, @location.length)
  colored_match_text = match_text.empty? ? match_text : match_text.ansi.red
  column = @location.column
  line = [@location.line, 1].max

  [
    "#{@file_path}:#{line} column: #{column} --- #{@message}",
    "  #{pre}#{colored_match_text}#{post}",
    "  #{pointers}",
  ].join("\n")
end