steep 1.8.0.dev.1 → 1.8.0.pre.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +33 -0
  3. data/README.md +3 -2
  4. data/bin/mem_graph.rb +67 -0
  5. data/bin/mem_prof.rb +102 -0
  6. data/bin/stackprof_test.rb +19 -0
  7. data/bin/steep-check.rb +251 -0
  8. data/guides/src/gem-rbs-collection/gem-rbs-collection.md +1 -1
  9. data/lib/steep/annotation_parser.rb +1 -1
  10. data/lib/steep/ast/builtin.rb +5 -5
  11. data/lib/steep/ast/node/type_application.rb +7 -6
  12. data/lib/steep/ast/types/any.rb +1 -9
  13. data/lib/steep/ast/types/boolean.rb +8 -16
  14. data/lib/steep/ast/types/bot.rb +2 -10
  15. data/lib/steep/ast/types/class.rb +1 -13
  16. data/lib/steep/ast/types/factory.rb +101 -85
  17. data/lib/steep/ast/types/instance.rb +1 -13
  18. data/lib/steep/ast/types/intersection.rb +8 -15
  19. data/lib/steep/ast/types/literal.rb +2 -8
  20. data/lib/steep/ast/types/logic.rb +3 -24
  21. data/lib/steep/ast/types/name.rb +5 -16
  22. data/lib/steep/ast/types/nil.rb +3 -12
  23. data/lib/steep/ast/types/proc.rb +4 -13
  24. data/lib/steep/ast/types/record.rb +21 -12
  25. data/lib/steep/ast/types/self.rb +1 -13
  26. data/lib/steep/ast/types/shared_instance.rb +11 -0
  27. data/lib/steep/ast/types/top.rb +1 -9
  28. data/lib/steep/ast/types/tuple.rb +4 -10
  29. data/lib/steep/ast/types/union.rb +10 -15
  30. data/lib/steep/ast/types/var.rb +4 -13
  31. data/lib/steep/ast/types/void.rb +2 -10
  32. data/lib/steep/diagnostic/ruby.rb +10 -10
  33. data/lib/steep/drivers/check.rb +11 -14
  34. data/lib/steep/drivers/checkfile.rb +8 -10
  35. data/lib/steep/drivers/stats.rb +17 -13
  36. data/lib/steep/drivers/utils/driver_helper.rb +24 -3
  37. data/lib/steep/drivers/watch.rb +3 -3
  38. data/lib/steep/interface/builder.rb +162 -138
  39. data/lib/steep/interface/method_type.rb +12 -20
  40. data/lib/steep/interface/shape.rb +66 -10
  41. data/lib/steep/interface/substitution.rb +2 -0
  42. data/lib/steep/interface/type_param.rb +20 -7
  43. data/lib/steep/located_value.rb +20 -0
  44. data/lib/steep/server/change_buffer.rb +5 -7
  45. data/lib/steep/server/custom_methods.rb +61 -0
  46. data/lib/steep/server/delay_queue.rb +8 -1
  47. data/lib/steep/server/interaction_worker.rb +13 -6
  48. data/lib/steep/server/lsp_formatter.rb +8 -6
  49. data/lib/steep/server/master.rb +195 -142
  50. data/lib/steep/server/type_check_worker.rb +25 -22
  51. data/lib/steep/server/work_done_progress.rb +64 -0
  52. data/lib/steep/server/worker_process.rb +1 -1
  53. data/lib/steep/services/completion_provider.rb +32 -24
  54. data/lib/steep/services/goto_service.rb +3 -2
  55. data/lib/steep/services/hover_provider/ruby.rb +30 -17
  56. data/lib/steep/services/signature_help_provider.rb +9 -7
  57. data/lib/steep/services/signature_service.rb +1 -1
  58. data/lib/steep/services/type_check_service.rb +19 -9
  59. data/lib/steep/signature/validator.rb +17 -20
  60. data/lib/steep/source.rb +47 -1
  61. data/lib/steep/subtyping/check.rb +105 -55
  62. data/lib/steep/subtyping/constraints.rb +13 -17
  63. data/lib/steep/type_construction.rb +106 -100
  64. data/lib/steep/type_inference/block_params.rb +8 -5
  65. data/lib/steep/type_inference/logic_type_interpreter.rb +11 -7
  66. data/lib/steep/type_inference/method_call.rb +3 -3
  67. data/lib/steep/type_inference/method_params.rb +1 -1
  68. data/lib/steep/type_inference/send_args.rb +1 -1
  69. data/lib/steep/typing.rb +164 -106
  70. data/lib/steep/version.rb +1 -1
  71. data/lib/steep.rb +29 -4
  72. data/steep.gemspec +2 -2
  73. metadata +16 -9
  74. data/lib/steep/type_inference/context_array.rb +0 -112
@@ -10,14 +10,18 @@ module Steep
10
10
  attr_reader :code_paths
11
11
  attr_reader :priority_paths
12
12
  attr_reader :checked_paths
13
+ attr_reader :work_done_progress
14
+ attr_reader :started_at
13
15
 
14
- def initialize(guid:)
16
+ def initialize(guid:, progress:)
15
17
  @guid = guid
16
18
  @library_paths = Set[]
17
19
  @signature_paths = Set[]
18
20
  @code_paths = Set[]
19
21
  @priority_paths = Set[]
20
22
  @checked_paths = Set[]
23
+ @work_done_progress = progress
24
+ @started_at = Time.now
21
25
  end
22
26
 
23
27
  def uri(path)
@@ -39,7 +43,7 @@ module Steep
39
43
  end
40
44
 
41
45
  def percentage
42
- checked_paths.size * 100 / all_paths.size
46
+ checked_paths.size * 100 / total
43
47
  end
44
48
 
45
49
  def all_paths
@@ -58,7 +62,7 @@ module Steep
58
62
  end
59
63
 
60
64
  def finished?
61
- unchecked_paths.empty?
65
+ total <= checked_paths.size
62
66
  end
63
67
 
64
68
  def unchecked_paths
@@ -150,6 +154,8 @@ module Steep
150
154
  def load(command_line_args:)
151
155
  loader = Services::FileLoader.new(base_dir: project.base_dir)
152
156
 
157
+ files = {} #: Hash[String, String]
158
+
153
159
  target_paths.each do |paths|
154
160
  target = paths.target
155
161
 
@@ -158,13 +164,25 @@ module Steep
158
164
 
159
165
  loader.each_path_in_patterns(target.source_pattern, command_line_args) do |path|
160
166
  paths.code_paths << project.absolute_path(path)
167
+ files[path.to_s] = project.absolute_path(path).read
168
+ if files.size > 1000
169
+ yield files.dup
170
+ files.clear
171
+ end
161
172
  end
162
173
  loader.each_path_in_patterns(target.signature_pattern) do |path|
163
174
  paths.signature_paths << project.absolute_path(path)
175
+ files[path.to_s] = project.absolute_path(path).read
176
+ if files.size > 1000
177
+ yield files.dup
178
+ files.clear
179
+ end
164
180
  end
165
181
 
166
182
  changed_paths.merge(paths.all_paths)
167
183
  end
184
+
185
+ yield files.dup unless files.empty?
168
186
  end
169
187
 
170
188
  def push_changes(path)
@@ -191,10 +209,10 @@ module Steep
191
209
  end
192
210
  end
193
211
 
194
- def make_request(guid: SecureRandom.uuid, last_request: nil, include_unchanged: false)
212
+ def make_request(guid: SecureRandom.uuid, last_request: nil, include_unchanged: false, progress:)
195
213
  return if changed_paths.empty? && !include_unchanged
196
214
 
197
- TypeCheckRequest.new(guid: guid).tap do |request|
215
+ TypeCheckRequest.new(guid: guid, progress: progress).tap do |request|
198
216
  if last_request
199
217
  request.library_paths.merge(last_request.unchecked_library_paths)
200
218
  request.signature_paths.merge(last_request.unchecked_signature_paths)
@@ -380,7 +398,7 @@ module Steep
380
398
  include MessageUtils
381
399
  end
382
400
 
383
- SendMessageJob = _ = Struct.new(:dest, :message, keyword_init: true) do
401
+ class SendMessageJob < Struct.new(:dest, :message, keyword_init: true)
384
402
  # @implements SendMessageJob
385
403
 
386
404
  def self.to_worker(worker, message:)
@@ -401,7 +419,7 @@ module Steep
401
419
  attr_reader :interaction_worker
402
420
  attr_reader :typecheck_workers
403
421
 
404
- attr_reader :job_queue
422
+ attr_reader :job_queue, :write_queue
405
423
 
406
424
  attr_reader :current_type_check_request
407
425
  attr_reader :controller
@@ -421,10 +439,11 @@ module Steep
421
439
  @typecheck_automatically = true
422
440
  @commandline_args = []
423
441
  @job_queue = queue
442
+ @write_queue = SizedQueue.new(100)
424
443
 
425
444
  @controller = TypeCheckController.new(project: project)
426
445
  @result_controller = ResultController.new()
427
- @start_type_checking_queue = DelayQueue.new(delay: 0.1)
446
+ @start_type_checking_queue = DelayQueue.new(delay: 0.3)
428
447
  end
429
448
 
430
449
  def start
@@ -459,6 +478,23 @@ module Steep
459
478
  end
460
479
  end
461
480
 
481
+ write_thread = Thread.new do
482
+ Steep.logger.formatter.push_tags(*tags)
483
+ Steep.logger.tagged "write" do
484
+ while job = write_queue.deq
485
+ # @type var job: SendMessageJob
486
+ case job.dest
487
+ when :client
488
+ Steep.logger.info { "Processing SendMessageJob: dest=client, method=#{job.message[:method] || "-"}, id=#{job.message[:id] || "-"}" }
489
+ writer.write job.message
490
+ when WorkerProcess
491
+ Steep.logger.info { "Processing SendMessageJob: dest=#{job.dest.name}, method=#{job.message[:method] || "-"}, id=#{job.message[:id] || "-"}" }
492
+ job.dest << job.message
493
+ end
494
+ end
495
+ end
496
+ end
497
+
462
498
  loop_thread = Thread.new do
463
499
  Steep.logger.formatter.push_tags(*tags)
464
500
  Steep.logger.tagged "main" do
@@ -488,15 +524,6 @@ module Steep
488
524
  end
489
525
  end
490
526
  end
491
- when SendMessageJob
492
- case job.dest
493
- when :client
494
- Steep.logger.info { "Processing SendMessageJob: dest=client, method=#{job.message[:method] || "-"}, id=#{job.message[:id] || "-"}" }
495
- writer.write job.message
496
- when WorkerProcess
497
- Steep.logger.info { "Processing SendMessageJob: dest=#{job.dest.name}, method=#{job.message[:method] || "-"}, id=#{job.message[:id] || "-"}" }
498
- job.dest << job.message
499
- end
500
527
  when Proc
501
528
  job.call()
502
529
  end
@@ -515,10 +542,14 @@ module Steep
515
542
  raise "Unexpected worker process exit"
516
543
  end
517
544
 
545
+ write_queue.close()
546
+ write_thread.join
547
+
518
548
  read_client_thread.join()
519
549
  worker_threads.each do |thread|
520
550
  thread.join
521
551
  end
552
+
522
553
  loop_thread.join
523
554
  end
524
555
  end
@@ -536,12 +567,18 @@ module Steep
536
567
  Steep::PathHelper.to_pathname(uri)
537
568
  end
538
569
 
570
+ def assign_initialize_params(params)
571
+ @initialize_params = params
572
+ end
573
+
539
574
  def work_done_progress_supported?
540
- initialize_params&.dig(:capabilities, :window, :workDoneProgress) ? true : false
575
+ initialize_params or raise "`initialize` request is not receiged yet"
576
+ initialize_params.dig(:capabilities, :window, :workDoneProgress) ? true : false
541
577
  end
542
578
 
543
579
  def file_system_watcher_supported?
544
- initialize_params&.dig(:capabilities, :workspace, :didChangeWatchedFiles, :dynamicRegistration) || false
580
+ initialize_params or raise "`initialize` request is not receiged yet"
581
+ initialize_params.dig(:capabilities, :workspace, :didChangeWatchedFiles, :dynamicRegistration) || false
545
582
  end
546
583
 
547
584
  def process_message_from_client(message)
@@ -550,16 +587,15 @@ module Steep
550
587
 
551
588
  case message[:method]
552
589
  when "initialize"
553
- @initialize_params = message[:params]
590
+ assign_initialize_params(message[:params])
591
+
554
592
  result_controller << group_request do |group|
555
593
  each_worker do |worker|
556
594
  group << send_request(method: "initialize", params: message[:params], worker: worker)
557
595
  end
558
596
 
559
597
  group.on_completion do
560
- controller.load(command_line_args: commandline_args)
561
-
562
- job_queue << SendMessageJob.to_client(
598
+ enqueue_write_job SendMessageJob.to_client(
563
599
  message: {
564
600
  id: id,
565
601
  result: LSP::Interface::InitializeResult.new(
@@ -590,6 +626,25 @@ module Steep
590
626
  }
591
627
  )
592
628
 
629
+ progress = work_done_progress(SecureRandom.uuid)
630
+ if typecheck_automatically
631
+ progress.begin("Type checking", "loading projects...", request_id: fresh_request_id)
632
+ end
633
+
634
+ Steep.measure("Load files from disk...") do
635
+ controller.load(command_line_args: commandline_args) do |input|
636
+ input.transform_values! do |content|
637
+ content.is_a?(String) or raise
638
+ if content.valid_encoding?
639
+ content
640
+ else
641
+ { text: Base64.encode64(content), binary: true }
642
+ end
643
+ end
644
+ broadcast_notification(CustomMethods::FileLoad.notification({ content: input }))
645
+ end
646
+ end
647
+
593
648
  if file_system_watcher_supported?
594
649
  patterns = [] #: Array[String]
595
650
  project.targets.each do |target|
@@ -615,7 +670,7 @@ module Steep
615
670
 
616
671
  Steep.logger.info { "Setting up didChangeWatchedFiles with pattern: #{patterns.inspect}" }
617
672
 
618
- job_queue << SendMessageJob.to_client(
673
+ enqueue_write_job SendMessageJob.to_client(
619
674
  message: {
620
675
  id: SecureRandom.uuid,
621
676
  method: "client/registerCapability",
@@ -635,13 +690,12 @@ module Steep
635
690
  }
636
691
  )
637
692
  end
638
- end
639
- end
640
693
 
641
- when "initialized"
642
- if typecheck_automatically
643
- if request = controller.make_request(include_unchanged: true)
644
- start_type_check(request, last_request: nil, start_progress: request.total > 10)
694
+ if typecheck_automatically
695
+ if request = controller.make_request(guid: progress.guid, include_unchanged: true, progress: progress)
696
+ start_type_check(request: request, last_request: nil)
697
+ end
698
+ end
645
699
  end
646
700
  end
647
701
 
@@ -663,10 +717,8 @@ module Steep
663
717
  content = ""
664
718
  end
665
719
 
666
- broadcast_notification({
667
- method: "$/file/reset",
668
- params: { uri: uri, content: content }
669
- })
720
+ content or raise
721
+ broadcast_notification(CustomMethods::FileReset.notification({ uri: uri, content: content }))
670
722
  end
671
723
  end
672
724
 
@@ -675,9 +727,13 @@ module Steep
675
727
  job_queue.push(
676
728
  -> do
677
729
  last_request = current_type_check_request
678
- if request = controller.make_request(last_request: last_request)
679
- start_type_check(request, last_request: last_request, start_progress: request.total > 10)
680
- end
730
+ guid = SecureRandom.uuid
731
+
732
+ start_type_check(
733
+ last_request: last_request,
734
+ include_unchanged: true,
735
+ progress: work_done_progress(guid)
736
+ )
681
737
  end
682
738
  )
683
739
  end
@@ -695,9 +751,12 @@ module Steep
695
751
  Steep.logger.info { "Starting type check from textDocument/didChange notification..." }
696
752
 
697
753
  last_request = current_type_check_request
698
- if request = controller.make_request(last_request: last_request)
699
- start_type_check(request, last_request: last_request, start_progress: request.total > 10)
700
- end
754
+ guid = SecureRandom.uuid
755
+
756
+ start_type_check(
757
+ last_request: last_request,
758
+ progress: work_done_progress(guid)
759
+ )
701
760
  end
702
761
  )
703
762
  end
@@ -710,10 +769,7 @@ module Steep
710
769
 
711
770
  if path = pathname(uri)
712
771
  controller.update_priority(open: path)
713
- broadcast_notification({
714
- method: "$/file/reset",
715
- params: { uri: uri, content: text }
716
- })
772
+ broadcast_notification(CustomMethods::FileReset.notification({ uri: uri, content: text }))
717
773
  end
718
774
 
719
775
  when "textDocument/didClose"
@@ -726,7 +782,7 @@ module Steep
726
782
  if path = pathname(message[:params][:textDocument][:uri])
727
783
  result_controller << send_request(method: message[:method], params: message[:params], worker: interaction_worker) do |handler|
728
784
  handler.on_completion do |response|
729
- job_queue << SendMessageJob.to_client(
785
+ enqueue_write_job SendMessageJob.to_client(
730
786
  message: {
731
787
  id: message[:id],
732
788
  result: response[:result]
@@ -735,7 +791,7 @@ module Steep
735
791
  end
736
792
  end
737
793
  else
738
- job_queue << SendMessageJob.to_client(
794
+ enqueue_write_job SendMessageJob.to_client(
739
795
  message: {
740
796
  id: message[:id],
741
797
  result: nil
@@ -752,27 +808,21 @@ module Steep
752
808
 
753
809
  group.on_completion do |handlers|
754
810
  result = handlers.flat_map(&:result)
755
- job_queue << SendMessageJob.to_client(message: { id: message[:id], result: result })
811
+ enqueue_write_job SendMessageJob.to_client(message: { id: message[:id], result: result })
756
812
  end
757
813
  end
758
814
 
759
- when "workspace/executeCommand"
760
- case message[:params][:command]
761
- when "steep/stats"
762
- result_controller << group_request do |group|
763
- typecheck_workers.each do |worker|
764
- group << send_request(method: "workspace/executeCommand", params: message[:params], worker: worker)
765
- end
815
+ when CustomMethods::Stats::METHOD
816
+ result_controller << group_request do |group|
817
+ typecheck_workers.each do |worker|
818
+ group << send_request(method: CustomMethods::Stats::METHOD, params: nil, worker: worker)
819
+ end
766
820
 
767
- group.on_completion do |handlers|
768
- stats = handlers.flat_map(&:result)
769
- job_queue << SendMessageJob.to_client(
770
- message: {
771
- id: message[:id],
772
- result: stats
773
- }
774
- )
775
- end
821
+ group.on_completion do |handlers|
822
+ stats = handlers.flat_map(&:result) #: Server::CustomMethods::Stats::result
823
+ enqueue_write_job SendMessageJob.to_client(
824
+ message: CustomMethods::Stats.response(message[:id], stats)
825
+ )
776
826
  end
777
827
  end
778
828
 
@@ -785,7 +835,7 @@ module Steep
785
835
 
786
836
  group.on_completion do |handlers|
787
837
  links = handlers.flat_map(&:result)
788
- job_queue << SendMessageJob.to_client(
838
+ enqueue_write_job SendMessageJob.to_client(
789
839
  message: {
790
840
  id: message[:id],
791
841
  result: links
@@ -794,7 +844,7 @@ module Steep
794
844
  end
795
845
  end
796
846
  else
797
- job_queue << SendMessageJob.to_client(
847
+ enqueue_write_job SendMessageJob.to_client(
798
848
  message: {
799
849
  id: message[:id],
800
850
  result: []
@@ -802,23 +852,18 @@ module Steep
802
852
  )
803
853
  end
804
854
 
805
- when "$/typecheck"
806
- request = controller.make_request(
807
- guid: message[:params][:guid],
855
+ when CustomMethods::TypeCheck::METHOD
856
+ params = message[:params] #: CustomMethods::TypeCheck::params
857
+ guid = params[:guid]
858
+
859
+ start_type_check(
808
860
  last_request: current_type_check_request,
809
- include_unchanged: true
861
+ include_unchanged: true,
862
+ progress: work_done_progress(guid || SecureRandom.uuid)
810
863
  )
811
864
 
812
- if request
813
- start_type_check(
814
- request,
815
- last_request: current_type_check_request,
816
- start_progress: true
817
- )
818
- end
819
-
820
865
  when "$/ping"
821
- job_queue << SendMessageJob.to_client(
866
+ enqueue_write_job SendMessageJob.to_client(
822
867
  message: {
823
868
  id: message[:id],
824
869
  result: message[:params]
@@ -826,13 +871,15 @@ module Steep
826
871
  )
827
872
 
828
873
  when "shutdown"
874
+ start_type_checking_queue.cancel
875
+
829
876
  result_controller << group_request do |group|
830
877
  each_worker do |worker|
831
878
  group << send_request(method: "shutdown", worker: worker)
832
879
  end
833
880
 
834
881
  group.on_completion do
835
- job_queue << SendMessageJob.to_client(message: { id: message[:id], result: nil })
882
+ enqueue_write_job SendMessageJob.to_client(message: { id: message[:id], result: nil })
836
883
  end
837
884
  end
838
885
 
@@ -853,67 +900,68 @@ module Steep
853
900
  end
854
901
  when message.key?(:method) && !message.key?(:id)
855
902
  case message[:method]
856
- when "$/typecheck/progress"
903
+ when CustomMethods::TypeCheck__Progress::METHOD
904
+ params = message[:params] #: CustomMethods::TypeCheck__Progress::params
857
905
  on_type_check_update(
858
- guid: message[:params][:guid],
859
- path: Pathname(message[:params][:path])
906
+ guid: params[:guid],
907
+ path: Pathname(params[:path])
860
908
  )
861
909
  else
862
910
  # Forward other notifications
863
- job_queue << SendMessageJob.to_client(message: message)
911
+ enqueue_write_job SendMessageJob.to_client(message: message)
864
912
  end
865
913
  end
866
914
  end
867
915
  end
868
916
 
869
- def start_type_check(request, last_request:, start_progress:)
870
- Steep.logger.tagged "#start_type_check(#{request.guid}, #{last_request&.guid}" do
871
- if last_request
872
- Steep.logger.info "Cancelling last request"
873
-
874
- job_queue << SendMessageJob.to_client(
875
- message: {
876
- method: "$/progress",
877
- params: {
878
- token: last_request.guid,
879
- value: { kind: "end" }
880
- }
917
+ def finish_type_check(request)
918
+ request.work_done_progress.end()
919
+
920
+ finished_at = Time.now
921
+ duration = finished_at - request.started_at
922
+
923
+ enqueue_write_job(
924
+ SendMessageJob.to_client(
925
+ message: CustomMethods::TypeCheck.response(
926
+ request.guid,
927
+ {
928
+ guid: request.guid,
929
+ completed: request.finished?,
930
+ started_at: request.started_at.iso8601,
931
+ finished_at: finished_at.iso8601,
932
+ duration: duration.to_i
881
933
  }
882
934
  )
935
+ )
936
+ )
937
+
938
+ nil
939
+ end
940
+
941
+ def start_type_check(request: nil, last_request:, progress: nil, include_unchanged: false, report_progress_threshold: 10)
942
+ Steep.logger.tagged "#start_type_check(#{progress&.guid || request&.guid}, #{last_request&.guid}" do
943
+ if last_request
944
+ finish_type_check(last_request)
945
+ end
946
+
947
+ unless request
948
+ progress or raise
949
+ request = controller.make_request(guid: progress.guid, include_unchanged: include_unchanged, progress: progress) or return
883
950
  end
884
951
 
885
- if start_progress
952
+ if request.total > report_progress_threshold
886
953
  Steep.logger.info "Starting new progress..."
887
954
 
888
955
  @current_type_check_request = request
889
956
 
890
- if work_done_progress_supported?
891
- job_queue << SendMessageJob.to_client(
892
- message: {
893
- id: fresh_request_id,
894
- method: "window/workDoneProgress/create",
895
- params: { token: request.guid }
896
- }
897
- )
957
+ if progress
958
+ # If `request:` keyword arg is not given
959
+ request.work_done_progress.begin("Type checking", request_id: fresh_request_id)
898
960
  end
899
961
 
900
- job_queue << SendMessageJob.to_client(
901
- message: {
902
- method: "$/progress",
903
- params: {
904
- token: request.guid,
905
- value: { kind: "begin", title: "Type checking", percentage: 0 }
906
- }
907
- }
908
- )
909
-
910
962
  if request.finished?
911
- job_queue << SendMessageJob.to_client(
912
- message: {
913
- method: "$/progress",
914
- params: { token: request.guid, value: { kind: "end" } }
915
- }
916
- )
963
+ @current_type_check_request = finish_type_check(request)
964
+ return
917
965
  end
918
966
  else
919
967
  @current_type_check_request = nil
@@ -926,12 +974,9 @@ module Steep
926
974
  index: worker.index || raise
927
975
  )
928
976
 
929
- job_queue << SendMessageJob.to_worker(
977
+ enqueue_write_job SendMessageJob.to_worker(
930
978
  worker,
931
- message: {
932
- method: "$/typecheck/start",
933
- params: request.as_json(assignment: assignment)
934
- }
979
+ message: CustomMethods::TypeCheck__Start.notification(request.as_json(assignment: assignment))
935
980
  )
936
981
  end
937
982
  end
@@ -942,22 +987,13 @@ module Steep
942
987
  if current.guid == guid
943
988
  current.checked(path)
944
989
  Steep.logger.info { "Request updated: checked=#{path}, unchecked=#{current.unchecked_paths.size}" }
945
- percentage = current.percentage
946
- value = if percentage == 100
947
- { kind: "end" }
948
- else
949
- progress_string = ("▮"*(percentage/5)) + ("▯"*(20 - percentage/5))
950
- { kind: "report", percentage: percentage, message: "#{progress_string}" }
951
- end
952
990
 
953
- job_queue << SendMessageJob.to_client(
954
- message: {
955
- method: "$/progress",
956
- params: { token: current.guid, value: value }
957
- }
958
- )
991
+ percentage = current.percentage
992
+ current.work_done_progress.report(percentage, "#{percentage}%")
959
993
 
960
- @current_type_check_request = nil if current.finished?
994
+ if current.finished?
995
+ @current_type_check_request = finish_type_check(current)
996
+ end
961
997
  end
962
998
  end
963
999
  end
@@ -965,13 +1001,13 @@ module Steep
965
1001
  def broadcast_notification(message)
966
1002
  Steep.logger.info "Broadcasting notification #{message[:method]}"
967
1003
  each_worker do |worker|
968
- job_queue << SendMessageJob.new(dest: worker, message: message)
1004
+ enqueue_write_job SendMessageJob.new(dest: worker, message: message)
969
1005
  end
970
1006
  end
971
1007
 
972
1008
  def send_notification(message, worker:)
973
1009
  Steep.logger.info "Sending notification #{message[:method]} to #{worker.name}"
974
- job_queue << SendMessageJob.new(dest: worker, message: message)
1010
+ enqueue_write_job SendMessageJob.new(dest: worker, message: message)
975
1011
  end
976
1012
 
977
1013
  def fresh_request_id
@@ -985,7 +1021,7 @@ module Steep
985
1021
  message = { method: method, id: id, params: params }
986
1022
  ResultHandler.new(request: message).tap do |handler|
987
1023
  yield handler if block
988
- job_queue << SendMessageJob.to_worker(worker, message: message)
1024
+ enqueue_write_job SendMessageJob.to_worker(worker, message: message)
989
1025
  end
990
1026
  end
991
1027
 
@@ -1000,6 +1036,23 @@ module Steep
1000
1036
  worker.kill
1001
1037
  end
1002
1038
  end
1039
+
1040
+ def enqueue_write_job(job)
1041
+ Steep.logger.info { "Write_queue has #{write_queue.size} items"}
1042
+ write_queue.push(job) # steep:ignore InsufficientKeywordArguments
1043
+ end
1044
+
1045
+ def work_done_progress(guid)
1046
+ if work_done_progress_supported?
1047
+ WorkDoneProgress.new(guid) do |message|
1048
+ enqueue_write_job SendMessageJob.to_client(message: message)
1049
+ end
1050
+ else
1051
+ WorkDoneProgress.new(guid) do |message|
1052
+ # nop
1053
+ end
1054
+ end
1055
+ end
1003
1056
  end
1004
1057
  end
1005
1058
  end