Class: Steep::Diagnostic::LSPFormatter

Inherits:
Object
  • Object
show all
Defined in:
lib/steep/diagnostic/lsp_formatter.rb

Constant Summary collapse

LSP =
LanguageServer::Protocol
ERROR =
:error
WARNING =
:warning
INFORMATION =
:information
HINT =
:hint

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config = {}, default_severity: ERROR) ⇒ LSPFormatter

Returns a new instance of LSPFormatter.



14
15
16
17
18
19
20
21
22
23
# File 'lib/steep/diagnostic/lsp_formatter.rb', line 14

def initialize(config = {}, default_severity: ERROR)
  @config = config
  @default_severity = default_severity

  config.each do |klass, severity|
    validate_severity(klass, severity)
    validate_class(klass)
  end
  validate_severity(:default, default_severity)
end

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



6
7
8
# File 'lib/steep/diagnostic/lsp_formatter.rb', line 6

def config
  @config
end

#default_severityObject (readonly)

Returns the value of attribute default_severity.



7
8
9
# File 'lib/steep/diagnostic/lsp_formatter.rb', line 7

def default_severity
  @default_severity
end

Instance Method Details

#format(diagnostic) ⇒ Object



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
72
73
74
# File 'lib/steep/diagnostic/lsp_formatter.rb', line 40

def format(diagnostic)
  severity = severity_for(diagnostic)

  if severity
    range = diagnostic.location&.as_lsp_range || raise("#{diagnostic.class} object (#{diagnostic.full_message}) instance must have `#location`")

    if diagnostic.is_a?(Ruby::Base)
      description = {
        href: "https://github.com/soutaro/steep/tree/v#{VERSION}/manual/ruby-diagnostics.md##{URI.encode_uri_component(diagnostic.diagnostic_code)}"
      } #: LSP::Interface::CodeDescription::json
    end

    tags = [] #: Array[LSP::Constant::DiagnosticTag::t]

    case diagnostic
    when Ruby::DeprecatedReference
      tags << LSP::Constant::DiagnosticTag::DEPRECATED
    when Signature::DeprecatedTypeName
      tags << LSP::Constant::DiagnosticTag::DEPRECATED
      severity = LSP::Constant::DiagnosticSeverity::WARNING
    end

    json = {
      message: diagnostic.full_message,
      code: diagnostic.diagnostic_code,
      severity: severity,
      range: range,
      codeDescription: description,
    } #: LSP::Interface::Diagnostic::json

    json[:tags] = tags unless tags.empty?

    json
  end
end

#severity_for(diagnostic) ⇒ Object



76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/steep/diagnostic/lsp_formatter.rb', line 76

def severity_for(diagnostic)
  case config.fetch(diagnostic.class, default_severity)
  when ERROR
    LSP::Constant::DiagnosticSeverity::ERROR
  when WARNING
    LSP::Constant::DiagnosticSeverity::WARNING
  when INFORMATION
    LSP::Constant::DiagnosticSeverity::INFORMATION
  when HINT
    LSP::Constant::DiagnosticSeverity::HINT
  when nil
    nil
  end
end

#validate_class(klass) ⇒ Object



25
26
27
28
29
# File 'lib/steep/diagnostic/lsp_formatter.rb', line 25

def validate_class(klass)
  unless klass < Diagnostic::Ruby::Base
    raise "Unexpected diagnostics class `#{klass}` given"
  end
end

#validate_severity(klass, severity) ⇒ Object



31
32
33
34
35
36
37
38
# File 'lib/steep/diagnostic/lsp_formatter.rb', line 31

def validate_severity(klass, severity)
  case severity
  when ERROR, WARNING, INFORMATION, HINT, nil
    # ok
  else
    raise "Unexpected severity `#{severity}` is specified for #{klass}"
  end
end