-
Notifications
You must be signed in to change notification settings - Fork 183
/
Copy pathdiagnostics.rb
108 lines (95 loc) · 3.33 KB
/
diagnostics.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# typed: strict
# frozen_string_literal: true
module RubyLsp
module Requests
# 
#
# The
# [diagnostics](https://microsoft.github.io/language-server-protocol/specification#textDocument_publishDiagnostics)
# request informs the editor of RuboCop offenses for a given file.
#
# # Example
#
# ```ruby
# def say_hello
# puts "Hello" # --> diagnostics: incorrect indentation
# end
# ```
class Diagnostics < Request
extend T::Sig
class << self
extend T::Sig
sig { returns(Interface::DiagnosticRegistrationOptions) }
def provider
Interface::DiagnosticRegistrationOptions.new(
document_selector: [Interface::DocumentFilter.new(language: "ruby")],
inter_file_dependencies: false,
workspace_diagnostics: false,
)
end
end
sig { params(global_state: GlobalState, document: RubyDocument).void }
def initialize(global_state, document)
super()
@active_linters = T.let(global_state.active_linters, T::Array[Support::Formatter])
@document = document
@uri = T.let(document.uri, URI::Generic)
end
sig { override.returns(T.nilable(T.all(T::Array[Interface::Diagnostic], Object))) }
def perform
diagnostics = []
diagnostics.concat(syntax_error_diagnostics, syntax_warning_diagnostics)
# Running RuboCop is slow, so to avoid excessive runs we only do so if the file is syntactically valid
return diagnostics if @document.syntax_error? || @active_linters.empty?
@active_linters.each do |linter|
linter_diagnostics = linter.run_diagnostic(@uri, @document)
diagnostics.concat(linter_diagnostics) if linter_diagnostics
end
diagnostics
end
private
sig { returns(T::Array[Interface::Diagnostic]) }
def syntax_warning_diagnostics
@document.parse_result.warnings.map do |warning|
location = warning.location
Interface::Diagnostic.new(
source: "Prism",
message: warning.message,
severity: Constant::DiagnosticSeverity::WARNING,
range: Interface::Range.new(
start: Interface::Position.new(
line: location.start_line - 1,
character: location.start_column,
),
end: Interface::Position.new(
line: location.end_line - 1,
character: location.end_column,
),
),
)
end
end
sig { returns(T::Array[Interface::Diagnostic]) }
def syntax_error_diagnostics
@document.parse_result.errors.map do |error|
location = error.location
Interface::Diagnostic.new(
range: Interface::Range.new(
start: Interface::Position.new(
line: location.start_line - 1,
character: location.start_column,
),
end: Interface::Position.new(
line: location.end_line - 1,
character: location.end_column,
),
),
message: error.message,
severity: Constant::DiagnosticSeverity::ERROR,
source: "Prism",
)
end
end
end
end
end