steep 1.8.3 → 1.9.0.dev.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +0 -22
- data/Steepfile +35 -26
- data/bin/rbs-inline +19 -0
- data/lib/steep/cli.rb +38 -5
- data/lib/steep/diagnostic/ruby.rb +11 -58
- data/lib/steep/drivers/annotations.rb +1 -1
- data/lib/steep/drivers/check.rb +103 -1
- data/lib/steep/drivers/checkfile.rb +10 -8
- data/lib/steep/drivers/print_project.rb +83 -40
- data/lib/steep/drivers/utils/driver_helper.rb +39 -6
- data/lib/steep/drivers/watch.rb +24 -2
- data/lib/steep/index/signature_symbol_provider.rb +8 -8
- data/lib/steep/interface/builder.rb +14 -1
- data/lib/steep/interface/function.rb +2 -2
- data/lib/steep/path_helper.rb +4 -2
- data/lib/steep/project/dsl.rb +176 -151
- data/lib/steep/project/group.rb +31 -0
- data/lib/steep/project/pattern.rb +4 -0
- data/lib/steep/project/target.rb +32 -6
- data/lib/steep/project.rb +38 -10
- data/lib/steep/server/custom_methods.rb +16 -0
- data/lib/steep/server/delay_queue.rb +0 -3
- data/lib/steep/server/interaction_worker.rb +2 -11
- data/lib/steep/server/master.rb +129 -279
- data/lib/steep/server/target_group_files.rb +205 -0
- data/lib/steep/server/type_check_controller.rb +366 -0
- data/lib/steep/server/type_check_worker.rb +60 -86
- data/lib/steep/services/file_loader.rb +23 -0
- data/lib/steep/services/goto_service.rb +40 -31
- data/lib/steep/services/hover_provider/singleton_methods.rb +4 -4
- data/lib/steep/services/path_assignment.rb +23 -4
- data/lib/steep/services/type_check_service.rb +76 -159
- data/lib/steep/signature/validator.rb +4 -4
- data/lib/steep/subtyping/check.rb +2 -2
- data/lib/steep/thread_waiter.rb +24 -16
- data/lib/steep/type_construction.rb +12 -3
- data/lib/steep/type_inference/block_params.rb +1 -2
- data/lib/steep/type_inference/context.rb +1 -1
- data/lib/steep/type_inference/type_env.rb +4 -4
- data/lib/steep/type_inference/type_env_builder.rb +1 -1
- data/lib/steep/version.rb +1 -1
- data/lib/steep.rb +6 -4
- data/sample/Steepfile +6 -0
- data/sample/lib/conference.rb +1 -5
- data/steep.gemspec +7 -1
- metadata +9 -6
- data/lib/steep/drivers/validate.rb +0 -65
data/lib/steep/server/master.rb
CHANGED
@@ -3,252 +3,6 @@ module Steep
|
|
3
3
|
class Master
|
4
4
|
LSP = LanguageServer::Protocol
|
5
5
|
|
6
|
-
class TypeCheckRequest
|
7
|
-
attr_reader :guid
|
8
|
-
attr_reader :library_paths
|
9
|
-
attr_reader :signature_paths
|
10
|
-
attr_reader :code_paths
|
11
|
-
attr_reader :priority_paths
|
12
|
-
attr_reader :checked_paths
|
13
|
-
attr_reader :work_done_progress
|
14
|
-
attr_reader :started_at
|
15
|
-
attr_accessor :needs_response
|
16
|
-
|
17
|
-
def initialize(guid:, progress:)
|
18
|
-
@guid = guid
|
19
|
-
@library_paths = Set[]
|
20
|
-
@signature_paths = Set[]
|
21
|
-
@code_paths = Set[]
|
22
|
-
@priority_paths = Set[]
|
23
|
-
@checked_paths = Set[]
|
24
|
-
@work_done_progress = progress
|
25
|
-
@started_at = Time.now
|
26
|
-
@needs_response = false
|
27
|
-
end
|
28
|
-
|
29
|
-
def uri(path)
|
30
|
-
Steep::PathHelper.to_uri(path)
|
31
|
-
end
|
32
|
-
|
33
|
-
def as_json(assignment:)
|
34
|
-
{
|
35
|
-
guid: guid,
|
36
|
-
library_uris: library_paths.grep(assignment).map {|path| uri(path).to_s },
|
37
|
-
signature_uris: signature_paths.grep(assignment).map {|path| uri(path).to_s },
|
38
|
-
code_uris: code_paths.grep(assignment).map {|path| uri(path).to_s },
|
39
|
-
priority_uris: priority_paths.map {|path| uri(path).to_s }
|
40
|
-
}
|
41
|
-
end
|
42
|
-
|
43
|
-
def total
|
44
|
-
library_paths.size + signature_paths.size + code_paths.size
|
45
|
-
end
|
46
|
-
|
47
|
-
def percentage
|
48
|
-
checked_paths.size * 100 / total
|
49
|
-
end
|
50
|
-
|
51
|
-
def all_paths
|
52
|
-
library_paths + signature_paths + code_paths
|
53
|
-
end
|
54
|
-
|
55
|
-
def checking_path?(path)
|
56
|
-
[library_paths, signature_paths, code_paths].any? do |paths|
|
57
|
-
paths.include?(path)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def checked(path)
|
62
|
-
raise unless checking_path?(path)
|
63
|
-
checked_paths << path
|
64
|
-
end
|
65
|
-
|
66
|
-
def finished?
|
67
|
-
total <= checked_paths.size
|
68
|
-
end
|
69
|
-
|
70
|
-
def unchecked_paths
|
71
|
-
all_paths - checked_paths
|
72
|
-
end
|
73
|
-
|
74
|
-
def unchecked_code_paths
|
75
|
-
code_paths - checked_paths
|
76
|
-
end
|
77
|
-
|
78
|
-
def unchecked_library_paths
|
79
|
-
library_paths - checked_paths
|
80
|
-
end
|
81
|
-
|
82
|
-
def unchecked_signature_paths
|
83
|
-
signature_paths - checked_paths
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
class TypeCheckController
|
88
|
-
attr_reader :project
|
89
|
-
attr_reader :priority_paths
|
90
|
-
attr_reader :changed_paths
|
91
|
-
attr_reader :target_paths
|
92
|
-
|
93
|
-
class TargetPaths
|
94
|
-
attr_reader :project
|
95
|
-
attr_reader :target
|
96
|
-
attr_reader :code_paths
|
97
|
-
attr_reader :signature_paths
|
98
|
-
attr_reader :library_paths
|
99
|
-
|
100
|
-
def initialize(project:, target:)
|
101
|
-
@project = project
|
102
|
-
@target = target
|
103
|
-
@code_paths = Set[]
|
104
|
-
@signature_paths = Set[]
|
105
|
-
@library_paths = Set[]
|
106
|
-
end
|
107
|
-
|
108
|
-
def all_paths
|
109
|
-
code_paths + signature_paths + library_paths
|
110
|
-
end
|
111
|
-
|
112
|
-
def library_path?(path)
|
113
|
-
library_paths.include?(path)
|
114
|
-
end
|
115
|
-
|
116
|
-
def signature_path?(path)
|
117
|
-
signature_paths.include?(path)
|
118
|
-
end
|
119
|
-
|
120
|
-
def code_path?(path)
|
121
|
-
code_paths.include?(path)
|
122
|
-
end
|
123
|
-
|
124
|
-
def add(path, library: false)
|
125
|
-
return true if signature_path?(path) || code_path?(path) || library_path?(path)
|
126
|
-
|
127
|
-
if library
|
128
|
-
library_paths << path
|
129
|
-
true
|
130
|
-
else
|
131
|
-
relative_path = project.relative_path(path)
|
132
|
-
|
133
|
-
case
|
134
|
-
when target.source_pattern =~ relative_path
|
135
|
-
code_paths << path
|
136
|
-
true
|
137
|
-
when target.signature_pattern =~ relative_path
|
138
|
-
signature_paths << path
|
139
|
-
true
|
140
|
-
else
|
141
|
-
false
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
alias << add
|
147
|
-
end
|
148
|
-
|
149
|
-
def initialize(project:)
|
150
|
-
@project = project
|
151
|
-
@priority_paths = Set[]
|
152
|
-
@changed_paths = Set[]
|
153
|
-
@target_paths = project.targets.each.map {|target| TargetPaths.new(project: project, target: target) }
|
154
|
-
end
|
155
|
-
|
156
|
-
def load(command_line_args:)
|
157
|
-
loader = Services::FileLoader.new(base_dir: project.base_dir)
|
158
|
-
|
159
|
-
files = {} #: Hash[String, String]
|
160
|
-
|
161
|
-
target_paths.each do |paths|
|
162
|
-
target = paths.target
|
163
|
-
|
164
|
-
signature_service = Services::SignatureService.load_from(target.new_env_loader(project: project))
|
165
|
-
paths.library_paths.merge(signature_service.env_rbs_paths)
|
166
|
-
|
167
|
-
loader.each_path_in_patterns(target.source_pattern, command_line_args) do |path|
|
168
|
-
paths.code_paths << project.absolute_path(path)
|
169
|
-
files[path.to_s] = project.absolute_path(path).read
|
170
|
-
if files.size > 1000
|
171
|
-
yield files.dup
|
172
|
-
files.clear
|
173
|
-
end
|
174
|
-
end
|
175
|
-
loader.each_path_in_patterns(target.signature_pattern) do |path|
|
176
|
-
paths.signature_paths << project.absolute_path(path)
|
177
|
-
files[path.to_s] = project.absolute_path(path).read
|
178
|
-
if files.size > 1000
|
179
|
-
yield files.dup
|
180
|
-
files.clear
|
181
|
-
end
|
182
|
-
end
|
183
|
-
|
184
|
-
changed_paths.merge(paths.all_paths)
|
185
|
-
end
|
186
|
-
|
187
|
-
yield files.dup unless files.empty?
|
188
|
-
end
|
189
|
-
|
190
|
-
def push_changes(path)
|
191
|
-
return if target_paths.any? {|paths| paths.library_path?(path) }
|
192
|
-
|
193
|
-
target_paths.each {|paths| paths << path }
|
194
|
-
|
195
|
-
if target_paths.any? {|paths| paths.code_path?(path) || paths.signature_path?(path) }
|
196
|
-
changed_paths << path
|
197
|
-
end
|
198
|
-
end
|
199
|
-
|
200
|
-
def update_priority(open: nil, close: nil)
|
201
|
-
path = open || close
|
202
|
-
path or raise
|
203
|
-
|
204
|
-
target_paths.each {|paths| paths << path }
|
205
|
-
|
206
|
-
case
|
207
|
-
when open
|
208
|
-
priority_paths << path
|
209
|
-
when close
|
210
|
-
priority_paths.delete path
|
211
|
-
end
|
212
|
-
end
|
213
|
-
|
214
|
-
def make_request(guid: SecureRandom.uuid, last_request: nil, include_unchanged: false, progress:)
|
215
|
-
return if changed_paths.empty? && !include_unchanged
|
216
|
-
|
217
|
-
TypeCheckRequest.new(guid: guid, progress: progress).tap do |request|
|
218
|
-
if last_request
|
219
|
-
request.library_paths.merge(last_request.unchecked_library_paths)
|
220
|
-
request.signature_paths.merge(last_request.unchecked_signature_paths)
|
221
|
-
request.code_paths.merge(last_request.unchecked_code_paths)
|
222
|
-
end
|
223
|
-
|
224
|
-
if include_unchanged
|
225
|
-
target_paths.each do |paths|
|
226
|
-
request.signature_paths.merge(paths.signature_paths)
|
227
|
-
request.library_paths.merge(paths.library_paths)
|
228
|
-
request.code_paths.merge(paths.code_paths)
|
229
|
-
end
|
230
|
-
else
|
231
|
-
updated_paths = target_paths.select {|paths| changed_paths.intersect?(paths.all_paths) }
|
232
|
-
|
233
|
-
updated_paths.each do |paths|
|
234
|
-
case
|
235
|
-
when paths.signature_paths.intersect?(changed_paths)
|
236
|
-
request.signature_paths.merge(paths.signature_paths)
|
237
|
-
request.library_paths.merge(paths.library_paths)
|
238
|
-
request.code_paths.merge(paths.code_paths)
|
239
|
-
when paths.code_paths.intersect?(changed_paths)
|
240
|
-
request.code_paths.merge(paths.code_paths & changed_paths)
|
241
|
-
end
|
242
|
-
end
|
243
|
-
end
|
244
|
-
|
245
|
-
request.priority_paths.merge(priority_paths)
|
246
|
-
|
247
|
-
changed_paths.clear()
|
248
|
-
end
|
249
|
-
end
|
250
|
-
end
|
251
|
-
|
252
6
|
class ResultHandler
|
253
7
|
attr_reader :request
|
254
8
|
attr_reader :completion_handler
|
@@ -424,6 +178,7 @@ module Steep
|
|
424
178
|
attr_reader :job_queue, :write_queue
|
425
179
|
|
426
180
|
attr_reader :current_type_check_request
|
181
|
+
attr_reader :current_diagnostics
|
427
182
|
attr_reader :controller
|
428
183
|
attr_reader :result_controller
|
429
184
|
|
@@ -442,6 +197,7 @@ module Steep
|
|
442
197
|
@commandline_args = []
|
443
198
|
@job_queue = queue
|
444
199
|
@write_queue = SizedQueue.new(100)
|
200
|
+
@current_diagnostics = {}
|
445
201
|
|
446
202
|
@controller = TypeCheckController.new(project: project)
|
447
203
|
@result_controller = ResultController.new()
|
@@ -533,7 +289,10 @@ module Steep
|
|
533
289
|
end
|
534
290
|
end
|
535
291
|
|
536
|
-
waiter = ThreadWaiter.new
|
292
|
+
waiter = ThreadWaiter.new
|
293
|
+
each_worker do |worker|
|
294
|
+
waiter << worker.wait_thread
|
295
|
+
end
|
537
296
|
waiter.wait_one()
|
538
297
|
|
539
298
|
unless job_queue.closed?
|
@@ -623,7 +382,11 @@ module Steep
|
|
623
382
|
declaration_provider: false,
|
624
383
|
implementation_provider: true,
|
625
384
|
type_definition_provider: true
|
626
|
-
)
|
385
|
+
),
|
386
|
+
server_info: {
|
387
|
+
name: "steep",
|
388
|
+
version: VERSION
|
389
|
+
}
|
627
390
|
)
|
628
391
|
}
|
629
392
|
)
|
@@ -647,6 +410,10 @@ module Steep
|
|
647
410
|
end
|
648
411
|
end
|
649
412
|
|
413
|
+
if typecheck_automatically
|
414
|
+
progress.end()
|
415
|
+
end
|
416
|
+
|
650
417
|
if file_system_watcher_supported?
|
651
418
|
patterns = [] #: Array[String]
|
652
419
|
project.targets.each do |target|
|
@@ -693,11 +460,13 @@ module Steep
|
|
693
460
|
)
|
694
461
|
end
|
695
462
|
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
463
|
+
controller.changed_paths.clear()
|
464
|
+
|
465
|
+
# if typecheck_automatically
|
466
|
+
# if request = controller.make_request(guid: progress.guid, include_unchanged: true, progress: progress)
|
467
|
+
# start_type_check(request: request, last_request: nil)
|
468
|
+
# end
|
469
|
+
# end
|
701
470
|
end
|
702
471
|
end
|
703
472
|
|
@@ -742,7 +511,6 @@ module Steep
|
|
742
511
|
|
743
512
|
start_type_check(
|
744
513
|
last_request: last_request,
|
745
|
-
include_unchanged: true,
|
746
514
|
progress: work_done_progress(guid),
|
747
515
|
needs_response: false
|
748
516
|
)
|
@@ -781,8 +549,15 @@ module Steep
|
|
781
549
|
text = message[:params][:textDocument][:text]
|
782
550
|
|
783
551
|
if path = pathname(uri)
|
784
|
-
|
785
|
-
|
552
|
+
if target = project.group_for_path(path)
|
553
|
+
controller.update_priority(open: path)
|
554
|
+
# broadcast_notification(CustomMethods::FileReset.notification({ uri: uri, content: text }))
|
555
|
+
|
556
|
+
start_type_checking_queue.execute do
|
557
|
+
guid = SecureRandom.uuid
|
558
|
+
start_type_check(last_request: current_type_check_request, progress: work_done_progress(guid), needs_response: true)
|
559
|
+
end
|
560
|
+
end
|
786
561
|
end
|
787
562
|
|
788
563
|
when "textDocument/didClose"
|
@@ -821,6 +596,7 @@ module Steep
|
|
821
596
|
|
822
597
|
group.on_completion do |handlers|
|
823
598
|
result = handlers.flat_map(&:result)
|
599
|
+
result.uniq!
|
824
600
|
enqueue_write_job SendMessageJob.to_client(message: { id: message[:id], result: result })
|
825
601
|
end
|
826
602
|
end
|
@@ -848,6 +624,7 @@ module Steep
|
|
848
624
|
|
849
625
|
group.on_completion do |handlers|
|
850
626
|
links = handlers.flat_map(&:result)
|
627
|
+
links.uniq!
|
851
628
|
enqueue_write_job SendMessageJob.to_client(
|
852
629
|
message: {
|
853
630
|
id: message[:id],
|
@@ -866,15 +643,35 @@ module Steep
|
|
866
643
|
end
|
867
644
|
|
868
645
|
when CustomMethods::TypeCheck::METHOD
|
646
|
+
id = message[:id]
|
869
647
|
params = message[:params] #: CustomMethods::TypeCheck::params
|
870
|
-
guid = params[:guid]
|
871
648
|
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
649
|
+
request = TypeCheckController::Request.new(guid: id, progress: work_done_progress(id))
|
650
|
+
request.needs_response = true
|
651
|
+
|
652
|
+
params[:code_paths].each do |target_name, path|
|
653
|
+
request.code_paths << [target_name.to_sym, Pathname(path)]
|
654
|
+
end
|
655
|
+
params[:signature_paths].each do |target_name, path|
|
656
|
+
request.signature_paths << [target_name.to_sym, Pathname(path)]
|
657
|
+
end
|
658
|
+
params[:library_paths].each do |target_name, path|
|
659
|
+
request.library_paths << [target_name.to_sym, Pathname(path)]
|
660
|
+
end
|
661
|
+
|
662
|
+
start_type_check(request: request, last_request: nil)
|
663
|
+
|
664
|
+
when CustomMethods::TypeCheckGroups::METHOD
|
665
|
+
params = message[:params] #: CustomMethods::TypeCheckGroups::params
|
666
|
+
|
667
|
+
groups = params.fetch(:groups)
|
668
|
+
|
669
|
+
progress = work_done_progress(SecureRandom.uuid)
|
670
|
+
progress.begin("Type checking #{groups.empty? ? "project" : groups.join(", ")}", request_id: fresh_request_id)
|
671
|
+
|
672
|
+
request = controller.make_group_request(groups, progress: progress)
|
673
|
+
request.needs_response = false
|
674
|
+
start_type_check(request: request, last_request: current_type_check_request, report_progress_threshold: 0)
|
878
675
|
|
879
676
|
when "$/ping"
|
880
677
|
enqueue_write_job SendMessageJob.to_client(
|
@@ -884,6 +681,25 @@ module Steep
|
|
884
681
|
}
|
885
682
|
)
|
886
683
|
|
684
|
+
when CustomMethods::Groups::METHOD
|
685
|
+
groups = [] #: Array[String]
|
686
|
+
|
687
|
+
project.targets.each do |target|
|
688
|
+
unless target.source_pattern.empty? && target.signature_pattern.empty?
|
689
|
+
groups << target.name.to_s
|
690
|
+
end
|
691
|
+
|
692
|
+
target.groups.each do |group|
|
693
|
+
unless group.source_pattern.empty? && group.signature_pattern.empty?
|
694
|
+
groups << "#{target.name}.#{group.name}"
|
695
|
+
end
|
696
|
+
end
|
697
|
+
end
|
698
|
+
|
699
|
+
enqueue_write_job(SendMessageJob.to_client(
|
700
|
+
message: CustomMethods::Groups.response(message[:id], groups)
|
701
|
+
))
|
702
|
+
|
887
703
|
when "shutdown"
|
888
704
|
start_type_checking_queue.cancel
|
889
705
|
|
@@ -916,9 +732,12 @@ module Steep
|
|
916
732
|
case message[:method]
|
917
733
|
when CustomMethods::TypeCheck__Progress::METHOD
|
918
734
|
params = message[:params] #: CustomMethods::TypeCheck__Progress::params
|
735
|
+
target = project.targets.find {|target| target.name.to_s == params[:target] } or raise
|
919
736
|
on_type_check_update(
|
920
737
|
guid: params[:guid],
|
921
|
-
path: Pathname(params[:path])
|
738
|
+
path: Pathname(params[:path]),
|
739
|
+
target: target,
|
740
|
+
diagnostics: params[:diagnostics]
|
922
741
|
)
|
923
742
|
else
|
924
743
|
# Forward other notifications
|
@@ -966,23 +785,35 @@ module Steep
|
|
966
785
|
request.needs_response = needs_response ? true : false
|
967
786
|
end
|
968
787
|
|
788
|
+
if last_request
|
789
|
+
request.merge!(last_request)
|
790
|
+
end
|
791
|
+
|
969
792
|
if request.total > report_progress_threshold
|
970
|
-
|
793
|
+
request.report_progress!
|
794
|
+
end
|
971
795
|
|
972
|
-
|
796
|
+
if request.each_unchecked_target_path.to_a.empty?
|
797
|
+
finish_type_check(request)
|
798
|
+
@current_type_check_request = nil
|
799
|
+
return
|
800
|
+
end
|
973
801
|
|
974
|
-
|
975
|
-
# If `request:` keyword arg is not given
|
976
|
-
request.work_done_progress.begin("Type checking", request_id: fresh_request_id)
|
977
|
-
end
|
802
|
+
Steep.logger.info "Starting new progress..."
|
978
803
|
|
979
|
-
|
980
|
-
|
981
|
-
|
982
|
-
|
804
|
+
@current_type_check_request = request
|
805
|
+
if last_request
|
806
|
+
checking_paths = request.each_path.to_set
|
807
|
+
current_diagnostics.keep_if do |path, _|
|
808
|
+
checking_paths.include?(path)
|
983
809
|
end
|
984
810
|
else
|
985
|
-
|
811
|
+
current_diagnostics.clear
|
812
|
+
end
|
813
|
+
|
814
|
+
if progress
|
815
|
+
# If `request:` keyword arg is not given
|
816
|
+
request.work_done_progress.begin("Type checking", request_id: fresh_request_id)
|
986
817
|
end
|
987
818
|
|
988
819
|
Steep.logger.info "Sending $/typecheck/start notifications"
|
@@ -1000,14 +831,17 @@ module Steep
|
|
1000
831
|
end
|
1001
832
|
end
|
1002
833
|
|
1003
|
-
def on_type_check_update(guid:, path:)
|
834
|
+
def on_type_check_update(guid:, path:, target:, diagnostics:)
|
1004
835
|
if current = current_type_check_request()
|
1005
836
|
if current.guid == guid
|
1006
|
-
current.checked(path)
|
1007
|
-
|
837
|
+
current.checked(path, target)
|
838
|
+
|
839
|
+
Steep.logger.info { "Request updated: checked=#{path}, unchecked=#{current.each_unchecked_code_target_path.size}, diagnostics=#{diagnostics&.size}" }
|
1008
840
|
|
1009
841
|
percentage = current.percentage
|
1010
|
-
current.work_done_progress.report(percentage, "#{
|
842
|
+
current.work_done_progress.report(percentage, "#{current.checked_paths.size}/#{current.total}") if current.report_progress
|
843
|
+
|
844
|
+
push_diagnostics(path, diagnostics)
|
1011
845
|
|
1012
846
|
if current.finished?
|
1013
847
|
finish_type_check(current)
|
@@ -1072,6 +906,22 @@ module Steep
|
|
1072
906
|
end
|
1073
907
|
end
|
1074
908
|
end
|
909
|
+
|
910
|
+
def push_diagnostics(path, diagnostics)
|
911
|
+
if diagnostics
|
912
|
+
ds = (current_diagnostics[path] ||= [])
|
913
|
+
|
914
|
+
ds.concat(diagnostics)
|
915
|
+
ds.uniq!
|
916
|
+
|
917
|
+
write_queue.push SendMessageJob.to_client(
|
918
|
+
message: {
|
919
|
+
method: :"textDocument/publishDiagnostics",
|
920
|
+
params: { uri: Steep::PathHelper.to_uri(path).to_s, diagnostics: ds }
|
921
|
+
}
|
922
|
+
)
|
923
|
+
end
|
924
|
+
end
|
1075
925
|
end
|
1076
926
|
end
|
1077
927
|
end
|