Class: Steep::Drivers::DiagnosticPrinter

Inherits:
Object
  • Object
show all
Defined in:
lib/steep/drivers/diagnostic_printer.rb

Constant Summary collapse

LSP =
LanguageServer::Protocol

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(stdout:, buffer:) ⇒ DiagnosticPrinter

Returns a new instance of DiagnosticPrinter.



9
10
11
12
# File 'lib/steep/drivers/diagnostic_printer.rb', line 9

def initialize(stdout:, buffer:)
  @stdout = stdout
  @buffer = buffer
end

Instance Attribute Details

#bufferObject (readonly)

Returns the value of attribute buffer.



7
8
9
# File 'lib/steep/drivers/diagnostic_printer.rb', line 7

def buffer
  @buffer
end

#stdoutObject (readonly)

Returns the value of attribute stdout.



6
7
8
# File 'lib/steep/drivers/diagnostic_printer.rb', line 6

def stdout
  @stdout
end

Instance Method Details

#color_severity(string, severity:) ⇒ Object



18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/steep/drivers/diagnostic_printer.rb', line 18

def color_severity(string, severity:)
  s = Rainbow(string)

  case severity
  when LSP::Constant::DiagnosticSeverity::ERROR
    s.red
  when LSP::Constant::DiagnosticSeverity::WARNING
    s.yellow
  when LSP::Constant::DiagnosticSeverity::INFORMATION
    s.blue
  else
    s
  end
end

#location(diagnostic) ⇒ Object



50
51
52
53
# File 'lib/steep/drivers/diagnostic_printer.rb', line 50

def location(diagnostic)
  start = diagnostic[:range][:start]
  Rainbow("#{path}:#{start[:line]+1}:#{start[:character]}").magenta
end

#pathObject



14
15
16
# File 'lib/steep/drivers/diagnostic_printer.rb', line 14

def path
  Pathname(buffer.name)
end


55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/steep/drivers/diagnostic_printer.rb', line 55

def print(diagnostic, prefix: "", source: true)
  header, *rest = diagnostic[:message].split(/\n/)

  stdout.puts "#{prefix}#{location(diagnostic)}: [#{severity_message(diagnostic[:severity])}] #{Rainbow(header).underline}"

  unless rest.empty?
    rest.each do |message|
      stdout.puts "#{prefix}│ #{message}"
    end
  end

  if diagnostic[:code]
    stdout.puts "#{prefix}│" unless rest.empty?
    stdout.puts "#{prefix}│ Diagnostic ID: #{diagnostic[:code]}"
  end

  stdout.puts "#{prefix}│"

  if source
    print_source_line(diagnostic, prefix: prefix)
  else
    stdout.puts "#{prefix}└ (no source code available)"
    stdout.puts "#{prefix}"
  end
end


81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/steep/drivers/diagnostic_printer.rb', line 81

def print_source_line(diagnostic, prefix: "")
  start_pos = diagnostic[:range][:start]
  end_pos = diagnostic[:range][:end]

  line = buffer.lines.fetch(start_pos[:line])

  leading = line[0...start_pos[:character]] || ""
  if start_pos[:line] == end_pos[:line]
    subject = line[start_pos[:character]...end_pos[:character]] || ""
    trailing = (line[end_pos[:character]...] || "").chomp
  else
    subject = (line[start_pos[:character]...] || "").chomp
    trailing = ""
  end

  unless subject.valid_encoding?
    subject.scrub!
  end

  stdout.puts "#{prefix}└ #{leading}#{color_severity(subject, severity: diagnostic[:severity])}#{trailing}"
  stdout.puts "#{prefix}  #{" " * leading.size}#{"~" * subject.size}"
end

#severity_message(severity) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/steep/drivers/diagnostic_printer.rb', line 33

def severity_message(severity)
  string = case severity
           when LSP::Constant::DiagnosticSeverity::ERROR
             "error"
           when LSP::Constant::DiagnosticSeverity::WARNING
             "warning"
           when LSP::Constant::DiagnosticSeverity::INFORMATION
             "information"
           when LSP::Constant::DiagnosticSeverity::HINT
             "hint"
           else
            raise
           end

  color_severity(string, severity: severity)
end