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

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.
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