steep 1.4.0 → 1.5.0.pre.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (112) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.vscode/steep-shared.code-snippets +41 -0
  4. data/CHANGELOG.md +37 -0
  5. data/Gemfile +2 -5
  6. data/Gemfile.lock +20 -17
  7. data/Gemfile.steep +1 -1
  8. data/Gemfile.steep.lock +6 -6
  9. data/Rakefile +198 -0
  10. data/Steepfile +3 -1
  11. data/lib/steep/ast/builtin.rb +9 -7
  12. data/lib/steep/ast/node/type_application.rb +13 -5
  13. data/lib/steep/ast/node/type_assertion.rb +28 -9
  14. data/lib/steep/ast/types/factory.rb +39 -7
  15. data/lib/steep/cli.rb +2 -1
  16. data/lib/steep/diagnostic/deprecated/else_on_exhaustive_case.rb +20 -0
  17. data/lib/steep/diagnostic/lsp_formatter.rb +3 -3
  18. data/lib/steep/diagnostic/ruby.rb +73 -12
  19. data/lib/steep/drivers/annotations.rb +1 -0
  20. data/lib/steep/drivers/check.rb +18 -13
  21. data/lib/steep/drivers/checkfile.rb +1 -1
  22. data/lib/steep/drivers/diagnostic_printer.rb +6 -4
  23. data/lib/steep/drivers/init.rb +2 -1
  24. data/lib/steep/drivers/print_project.rb +3 -1
  25. data/lib/steep/drivers/stats.rb +1 -1
  26. data/lib/steep/drivers/utils/driver_helper.rb +10 -8
  27. data/lib/steep/drivers/utils/jobs_option.rb +6 -1
  28. data/lib/steep/drivers/validate.rb +9 -5
  29. data/lib/steep/drivers/watch.rb +8 -3
  30. data/lib/steep/expectations.rb +144 -75
  31. data/lib/steep/index/signature_symbol_provider.rb +22 -13
  32. data/lib/steep/node_helper.rb +172 -0
  33. data/lib/steep/server/base_worker.rb +2 -1
  34. data/lib/steep/server/change_buffer.rb +17 -15
  35. data/lib/steep/server/interaction_worker.rb +20 -0
  36. data/lib/steep/server/lsp_formatter.rb +20 -1
  37. data/lib/steep/server/master.rb +51 -36
  38. data/lib/steep/server/type_check_worker.rb +18 -2
  39. data/lib/steep/server/worker_process.rb +19 -2
  40. data/lib/steep/services/completion_provider.rb +189 -3
  41. data/lib/steep/services/file_loader.rb +1 -1
  42. data/lib/steep/services/goto_service.rb +123 -27
  43. data/lib/steep/services/signature_help_provider.rb +1 -6
  44. data/lib/steep/signature/validator.rb +6 -1
  45. data/lib/steep/source.rb +165 -108
  46. data/lib/steep/subtyping/check.rb +5 -3
  47. data/lib/steep/subtyping/variable_variance.rb +11 -0
  48. data/lib/steep/thread_waiter.rb +35 -0
  49. data/lib/steep/type_construction.rb +416 -171
  50. data/lib/steep/type_inference/block_params.rb +50 -9
  51. data/lib/steep/type_inference/context.rb +4 -0
  52. data/lib/steep/type_inference/context_array.rb +6 -6
  53. data/lib/steep/type_inference/logic_type_interpreter.rb +202 -68
  54. data/lib/steep/typing.rb +5 -4
  55. data/lib/steep/version.rb +1 -1
  56. data/lib/steep.rb +21 -14
  57. data/sample/Steepfile +1 -0
  58. data/sig/shims/bundler.rbs +3 -0
  59. data/sig/shims/language-server_protocol.rbs +151 -10
  60. data/sig/shims/parser/nodes.rbs +210 -0
  61. data/sig/shims/parser.rbs +10 -0
  62. data/sig/steep/ast/builtin.rbs +2 -2
  63. data/sig/steep/ast/node/type_application.rbs +2 -2
  64. data/sig/steep/ast/node/type_assertion.rbs +8 -2
  65. data/sig/steep/ast/types/factory.rbs +28 -1
  66. data/sig/steep/diagnostic/deprecated/else_on_exhaustive_case.rbs +13 -0
  67. data/sig/steep/diagnostic/lsp_formatter.rbs +5 -2
  68. data/sig/steep/diagnostic/ruby.rbs +76 -6
  69. data/sig/steep/drivers/annotations.rbs +5 -5
  70. data/sig/steep/drivers/check.rbs +11 -11
  71. data/sig/steep/drivers/diagnostic_printer.rbs +9 -9
  72. data/sig/steep/drivers/init.rbs +6 -6
  73. data/sig/steep/drivers/print_project.rbs +4 -4
  74. data/sig/steep/drivers/utils/driver_helper.rbs +8 -6
  75. data/sig/steep/drivers/validate.rbs +4 -4
  76. data/sig/steep/drivers/watch.rbs +1 -1
  77. data/sig/steep/expectations.rbs +72 -0
  78. data/sig/steep/index/signature_symbol_provider.rbs +22 -10
  79. data/sig/steep/interface/block.rbs +2 -0
  80. data/sig/steep/interface/function.rbs +2 -2
  81. data/sig/steep/node_helper.rbs +56 -0
  82. data/sig/steep/path_helper.rbs +1 -1
  83. data/sig/steep/project/options.rbs +1 -1
  84. data/sig/steep/range_extension.rbs +2 -2
  85. data/sig/steep/server/master.rbs +16 -2
  86. data/sig/steep/server/type_check_worker.rbs +5 -1
  87. data/sig/steep/server/worker_process.rbs +5 -1
  88. data/sig/steep/services/completion_provider.rbs +31 -1
  89. data/sig/steep/services/goto_service.rbs +80 -19
  90. data/sig/steep/source.rbs +27 -4
  91. data/sig/steep/subtyping/variable_variance.rbs +9 -9
  92. data/sig/steep/thread_waiter.rbs +13 -0
  93. data/sig/steep/type_construction.rbs +26 -9
  94. data/sig/steep/type_inference/block_params.rbs +13 -1
  95. data/sig/steep/type_inference/context.rbs +5 -1
  96. data/sig/steep/type_inference/context_array.rbs +16 -15
  97. data/sig/steep/type_inference/logic_type_interpreter.rbs +36 -6
  98. data/sig/steep/type_inference/type_env_builder.rbs +4 -0
  99. data/sig/steep/typing.rbs +22 -20
  100. data/sig/steep.rbs +14 -13
  101. data/smoke/and/a.rb +1 -1
  102. data/smoke/and/test_expectations.yml +5 -7
  103. data/smoke/diagnostics/incompatible_annotation.rb +1 -1
  104. data/smoke/diagnostics/test_expectations.yml +2 -2
  105. data/smoke/enumerator/a.rb +0 -7
  106. data/smoke/enumerator/b.rb +0 -2
  107. data/smoke/enumerator/test_expectations.yml +17 -105
  108. data/smoke/lambda/a.rb +0 -5
  109. data/smoke/lambda/test_expectations.yml +0 -22
  110. data/smoke/type_case/test_expectations.yml +10 -0
  111. data/steep.gemspec +2 -2
  112. metadata +16 -9
data/lib/steep/cli.rb CHANGED
@@ -192,7 +192,8 @@ module Steep
192
192
  OptionParser.new do |opts|
193
193
  opts.banner = "Usage: steep watch [options] [dirs]"
194
194
  opts.on("--severity-level=LEVEL", /^error|warning|information|hint$/, "Specify the minimum diagnostic severity to be recognized as an error (defaults: warning): error, warning, information, or hint") do |level|
195
- command.severity_level = level.to_sym
195
+ # @type var level: String
196
+ command.severity_level = _ = level.to_sym
196
197
  end
197
198
  handle_jobs_option command.jobs_option, opts
198
199
  handle_logging_options opts
@@ -0,0 +1,20 @@
1
+ Steep.logger.error "Diagnostic `Ruby::ElseOnExhaustiveCase` is deprecated. Use `Ruby::UnreachableBranch` instead."
2
+
3
+ module Steep
4
+ module Diagnostic
5
+ module Ruby
6
+ class ElseOnExhaustiveCase < Base
7
+ attr_reader :type
8
+
9
+ def initialize(node:, type:)
10
+ super(node: node)
11
+ @type = type
12
+ end
13
+
14
+ def header_line
15
+ "The branch is unreachable because the condition is exhaustive"
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -41,14 +41,14 @@ module Steep
41
41
  severity = severity_for(diagnostic)
42
42
 
43
43
  if severity
44
- range = diagnostic.location&.as_lsp_range or raise "#{diagnostic.class} object (#{diagnostic.full_message}) instance must have `#location`"
44
+ range = diagnostic.location&.as_lsp_range || raise("#{diagnostic.class} object (#{diagnostic.full_message}) instance must have `#location`")
45
45
 
46
- LSP::Interface::Diagnostic.new(
46
+ {
47
47
  message: diagnostic.full_message,
48
48
  code: diagnostic.diagnostic_code,
49
49
  severity: severity,
50
50
  range: range
51
- ).to_hash
51
+ }
52
52
  end
53
53
  end
54
54
 
@@ -322,6 +322,24 @@ module Steep
322
322
  end
323
323
  end
324
324
 
325
+ class SetterReturnTypeMismatch < Base
326
+ attr_reader :expected, :actual, :result, :method_name
327
+
328
+ include ResultPrinter
329
+
330
+ def initialize(node:, method_name:, expected:, actual:, result:)
331
+ super(node: node)
332
+ @method_name = method_name
333
+ @expected = expected
334
+ @actual = actual
335
+ @result = result
336
+ end
337
+
338
+ def header_line
339
+ "The setter method `#{method_name}` cannot return a value of type `#{actual}` because declared as type `#{expected}`"
340
+ end
341
+ end
342
+
325
343
  class UnexpectedBlockGiven < Base
326
344
  attr_reader :method_type
327
345
 
@@ -539,6 +557,24 @@ module Steep
539
557
  end
540
558
  end
541
559
 
560
+ class SetterBodyTypeMismatch < Base
561
+ attr_reader :expected, :actual, :result, :method_name
562
+
563
+ include ResultPrinter
564
+
565
+ def initialize(node:, expected:, actual:, result:, method_name:)
566
+ super(node: node, location: node.loc.name)
567
+ @expected = expected
568
+ @actual = actual
569
+ @result = result
570
+ @method_name = method_name
571
+ end
572
+
573
+ def header_line
574
+ "Setter method `#{method_name}` cannot have type `#{actual}` because declared as type `#{expected}`"
575
+ end
576
+ end
577
+
542
578
  class UnexpectedYield < Base
543
579
  def header_line
544
580
  "No block given for `yield`"
@@ -626,6 +662,7 @@ module Steep
626
662
  end
627
663
 
628
664
  autoload :UnknownConstantAssigned, "steep/diagnostic/deprecated/unknown_constant_assigned"
665
+ autoload :ElseOnExhaustiveCase, "steep/diagnostic/deprecated/else_on_exhaustive_case"
629
666
 
630
667
  class UnknownInstanceVariable < Base
631
668
  attr_reader :name
@@ -724,16 +761,9 @@ module Steep
724
761
  end
725
762
  end
726
763
 
727
- class ElseOnExhaustiveCase < Base
728
- attr_reader :type
729
-
730
- def initialize(node:, type:)
731
- super(node: node)
732
- @type = type
733
- end
734
-
764
+ class UnreachableBranch < Base
735
765
  def header_line
736
- "The branch is unreachable because the condition is exhaustive"
766
+ "The branch is unreachable"
737
767
  end
738
768
  end
739
769
 
@@ -908,6 +938,19 @@ module Steep
908
938
  end
909
939
  end
910
940
 
941
+ class ProcHintIgnored < Base
942
+ attr_reader :hint_type, :block_node
943
+
944
+ def initialize(hint_type:, node:)
945
+ @hint_type = hint_type
946
+ super(node: node)
947
+ end
948
+
949
+ def header_line
950
+ "The type hint given to the block is ignored: `#{hint_type}`"
951
+ end
952
+ end
953
+
911
954
  ALL = ObjectSpace.each_object(Class).with_object([]) do |klass, array|
912
955
  if klass < Base
913
956
  array << klass
@@ -931,7 +974,11 @@ module Steep
931
974
  FalseAssertion => :information,
932
975
  UnexpectedTypeArgument => :information,
933
976
  InsufficientTypeArgument => :information,
934
- UnexpectedTypeArgument => :information
977
+ UnexpectedTypeArgument => :information,
978
+ UnsupportedSyntax => nil,
979
+ ProcHintIgnored => :information,
980
+ SetterBodyTypeMismatch => nil,
981
+ SetterReturnTypeMismatch => nil
935
982
  }
936
983
  ).freeze
937
984
  end
@@ -944,7 +991,11 @@ module Steep
944
991
  FallbackAny => nil,
945
992
  ElseOnExhaustiveCase => nil,
946
993
  UnknownConstant => nil,
947
- MethodDefinitionMissing => nil
994
+ MethodDefinitionMissing => nil,
995
+ UnsupportedSyntax => nil,
996
+ ProcHintIgnored => :warning,
997
+ SetterBodyTypeMismatch => :error,
998
+ SetterReturnTypeMismatch => :error
948
999
  }
949
1000
  ).freeze
950
1001
  end
@@ -959,10 +1010,20 @@ module Steep
959
1010
  UnknownConstant => nil,
960
1011
  MethodDefinitionMissing => nil,
961
1012
  UnexpectedJump => nil,
962
- FalseAssertion => :hint
1013
+ FalseAssertion => :hint,
1014
+ UnsupportedSyntax => nil,
1015
+ ProcHintIgnored => :hint,
1016
+ SetterBodyTypeMismatch => nil,
1017
+ SetterReturnTypeMismatch => nil
963
1018
  }
964
1019
  ).freeze
965
1020
  end
1021
+
1022
+ def self.silent
1023
+ @silent ||= ALL.each.with_object({}) do |klass, hash|
1024
+ hash[klass] = nil
1025
+ end.freeze
1026
+ end
966
1027
  end
967
1028
  end
968
1029
  end
@@ -37,6 +37,7 @@ module Steep
37
37
  loc = node.loc
38
38
  stdout.puts "#{path}:#{loc.line}:#{loc.column}:#{node.type}:\t#{node.loc.expression.source.lines.first}"
39
39
  annotations.each do |annotation|
40
+ annotation.location or raise
40
41
  stdout.puts " #{annotation.location.source}"
41
42
  end
42
43
  end
@@ -55,9 +55,9 @@ module Steep
55
55
  master.commandline_args.push(*command_line_patterns)
56
56
 
57
57
  main_thread = Thread.start do
58
+ Thread.current.abort_on_exception = true
58
59
  master.start()
59
60
  end
60
- main_thread.abort_on_exception = true
61
61
 
62
62
  Steep.logger.info { "Initializing server" }
63
63
  initialize_id = request_id()
@@ -68,13 +68,13 @@ module Steep
68
68
  Steep.logger.info { "Starting type checking: #{request_guid}" }
69
69
  client_writer.write({ method: "$/typecheck", params: { guid: request_guid } })
70
70
 
71
- diagnostic_notifications = []
72
- error_messages = []
71
+ diagnostic_notifications = [] #: Array[LanguageServer::Protocol::Interface::PublishDiagnosticsParams]
72
+ error_messages = [] #: Array[String]
73
73
  client_reader.read do |response|
74
74
  case
75
75
  when response[:method] == "textDocument/publishDiagnostics"
76
76
  ds = response[:params][:diagnostics]
77
- ds.select! {|d| keep_diagnostic?(d) }
77
+ ds.select! {|d| keep_diagnostic?(d, severity_level: severity_level) }
78
78
  if ds.empty?
79
79
  stdout.print "."
80
80
  else
@@ -130,6 +130,9 @@ module Steep
130
130
  stdout.puts Rainbow("Unexpected error reported. 🚨").red.bold
131
131
  1
132
132
  end
133
+ rescue Errno::EPIPE => error
134
+ stdout.puts Rainbow("Steep shutdown with an error: #{error.inspect}").red.bold
135
+ return 1
133
136
  end
134
137
 
135
138
  def print_expectations(project:, all_files:, expectations_path:, notifications:)
@@ -139,9 +142,11 @@ module Steep
139
142
  unexpected_count = 0
140
143
  missing_count = 0
141
144
 
142
- ns = notifications.each.with_object({}) do |notification, hash|
143
- path = project.relative_path(Steep::PathHelper.to_pathname(notification[:uri]))
144
- hash[path] = notification[:diagnostics]
145
+ ns = notifications.each.with_object({}) do |notification, hash| #$ Hash[Pathname, Array[Expectations::Diagnostic]]
146
+ path = project.relative_path(Steep::PathHelper.to_pathname(notification[:uri]) || raise)
147
+ hash[path] = notification[:diagnostics].map do |diagnostic|
148
+ Expectations::Diagnostic.from_lsp(diagnostic)
149
+ end
145
150
  end
146
151
 
147
152
  all_files.sort.each do |path|
@@ -156,10 +161,10 @@ module Steep
156
161
  expected_count += 1
157
162
  when :unexpected
158
163
  unexpected_count += 1
159
- printer.print(diag, prefix: Rainbow("+ ").green)
164
+ printer.print(diag.to_lsp, prefix: Rainbow("+ ").green)
160
165
  when :missing
161
166
  missing_count += 1
162
- printer.print(diag, prefix: Rainbow("- ").red, source: false)
167
+ printer.print(diag.to_lsp, prefix: Rainbow("- ").red, source: false)
163
168
  end
164
169
  end
165
170
  end
@@ -186,9 +191,9 @@ module Steep
186
191
  Expectations.empty()
187
192
  end
188
193
 
189
- ns = notifications.each.with_object({}) do |notification, hash|
190
- path = project.relative_path(Steep::PathHelper.to_pathname(notification[:uri]))
191
- hash[path] = notification[:diagnostics]
194
+ ns = notifications.each.with_object({}) do |notification, hash| #$ Hash[Pathname, Array[Expectations::Diagnostic]]
195
+ path = project.relative_path(Steep::PathHelper.to_pathname(notification[:uri]) || raise)
196
+ hash[path] = notification[:diagnostics].map {|diagnostic| Expectations::Diagnostic.from_lsp(diagnostic) }
192
197
  end
193
198
 
194
199
  all_files.sort.each do |path|
@@ -216,7 +221,7 @@ module Steep
216
221
  total = errors.sum {|notification| notification[:diagnostics].size }
217
222
 
218
223
  errors.each do |notification|
219
- path = Steep::PathHelper.to_pathname(notification[:uri])
224
+ path = Steep::PathHelper.to_pathname(notification[:uri]) or raise
220
225
  buffer = RBS::Buffer.new(name: project.relative_path(path), content: path.read)
221
226
  printer = DiagnosticPrinter.new(buffer: buffer, stdout: stdout)
222
227
 
@@ -119,9 +119,9 @@ module Steep
119
119
  master.typecheck_automatically = false
120
120
 
121
121
  main_thread = Thread.start do
122
+ Thread.current.abort_on_exception = true
122
123
  master.start()
123
124
  end
124
- main_thread.abort_on_exception = true
125
125
 
126
126
  Steep.logger.info { "Initializing server" }
127
127
  initialize_id = request_id()
@@ -12,7 +12,7 @@ module Steep
12
12
  end
13
13
 
14
14
  def path
15
- buffer.name
15
+ Pathname(buffer.name)
16
16
  end
17
17
 
18
18
  def color_severity(string, severity:)
@@ -40,6 +40,8 @@ module Steep
40
40
  "information"
41
41
  when LSP::Constant::DiagnosticSeverity::HINT
42
42
  "hint"
43
+ else
44
+ raise
43
45
  end
44
46
 
45
47
  color_severity(string, severity: severity)
@@ -82,12 +84,12 @@ module Steep
82
84
 
83
85
  line = buffer.lines[start_pos[:line]]
84
86
 
85
- leading = line[0...start_pos[:character]]
87
+ leading = line[0...start_pos[:character]] || ""
86
88
  if start_pos[:line] == end_pos[:line]
87
- subject = line[start_pos[:character]...end_pos[:character]]
89
+ subject = line[start_pos[:character]...end_pos[:character]] || ""
88
90
  trailing = (line[end_pos[:character]...] || "").chomp
89
91
  else
90
- subject = line[start_pos[:character]...].chomp
92
+ subject = (line[start_pos[:character]...] || "").chomp
91
93
  trailing = ""
92
94
  end
93
95
 
@@ -20,9 +20,10 @@ module Steep
20
20
  #
21
21
  # # library "pathname", "set" # Standard libraries
22
22
  # # library "strong_json" # Gems
23
- #
23
+ #
24
24
  # # configure_code_diagnostics(D::Ruby.strict) # `strict` diagnostics setting
25
25
  # # configure_code_diagnostics(D::Ruby.lenient) # `lenient` diagnostics setting
26
+ # # configure_code_diagnostics(D::Ruby.silent) # `silent` diagnostics setting
26
27
  # # configure_code_diagnostics do |hash| # You can setup everything yourself
27
28
  # # hash[D::Ruby::NoMethod] = :information
28
29
  # # end
@@ -54,8 +54,10 @@ module Steep
54
54
  case lib
55
55
  when :core
56
56
  stdout.puts " - core: #{path}"
57
+ when Pathname
58
+ raise "Unexpected pathname from loader: path=#{path}"
57
59
  else
58
- stdout.puts " - #{lib.name}: #{path}"
60
+ stdout.puts " - #{lib.name}(#{lib.version}): #{path}"
59
61
  end
60
62
  end
61
63
  end
@@ -145,9 +145,9 @@ module Steep
145
145
  master.commandline_args.push(*command_line_patterns)
146
146
 
147
147
  main_thread = Thread.start do
148
+ Thread.current.abort_on_exception = true
148
149
  master.start()
149
150
  end
150
- main_thread.abort_on_exception = true
151
151
 
152
152
  initialize_id = request_id()
153
153
  client_writer.write({ method: :initialize, id: initialize_id })
@@ -10,13 +10,15 @@ module Steep
10
10
  steep_file_path = path.absolute? ? path : Pathname.pwd + path
11
11
  Project.new(steepfile_path: steep_file_path).tap do |project|
12
12
  Project::DSL.parse(project, path.read, filename: path.to_s)
13
- end
14
- end
15
13
 
16
- def type_check(project)
17
- project.targets.each do |target|
18
- Steep.logger.tagged "target=#{target.name}" do
19
- target.type_check
14
+ project.targets.each do |target|
15
+ if collection_lock = target.options.collection_lock
16
+ begin
17
+ collection_lock.check_rbs_availability!
18
+ rescue RBS::Collection::Config::CollectionNotAvailable
19
+ raise "Run `rbs collection install` to install type definitions"
20
+ end
21
+ end
20
22
  end
21
23
  end
22
24
  end
@@ -56,10 +58,10 @@ module Steep
56
58
  end
57
59
  end
58
60
 
59
- def keep_diagnostic?(diagnostic)
61
+ def keep_diagnostic?(diagnostic, severity_level:)
60
62
  severity = diagnostic[:severity]
61
63
 
62
- case self.severity_level
64
+ case severity_level
63
65
  when nil, :hint
64
66
  true
65
67
  when :error
@@ -13,7 +13,12 @@ module Steep
13
13
  end
14
14
 
15
15
  def jobs_count_value
16
- jobs_count || default_jobs_count
16
+ count = jobs_count || default_jobs_count
17
+ if count >= 1
18
+ count
19
+ else
20
+ 1
21
+ end
17
22
  end
18
23
  end
19
24
  end
@@ -33,21 +33,25 @@ module Steep
33
33
  builder = Interface::Builder.new(factory)
34
34
  check = Subtyping::Check.new(builder: builder)
35
35
  Signature::Validator.new(checker: check).tap {|v| v.validate() }.each_error.to_a
36
+ else
37
+ raise
36
38
  end
37
39
  end
38
40
 
39
41
  any_error ||= !errors.empty?
40
42
 
41
43
  formatter = Diagnostic::LSPFormatter.new({})
42
- diagnostics = errors.group_by {|e| e.location.buffer }.transform_values do |errors|
44
+ diagnostics = errors.group_by {|e| e.location&.buffer }.transform_values do |errors|
43
45
  errors.map {|error| formatter.format(error) }
44
46
  end
45
47
 
46
48
  diagnostics.each do |buffer, ds|
47
- printer = DiagnosticPrinter.new(stdout: stdout, buffer: buffer)
48
- ds.each do |d|
49
- printer.print(d)
50
- stdout.puts
49
+ if buffer
50
+ printer = DiagnosticPrinter.new(stdout: stdout, buffer: buffer)
51
+ ds.each do |d|
52
+ printer.print(d)
53
+ stdout.puts
54
+ end
51
55
  end
52
56
  end
53
57
  end
@@ -57,7 +57,6 @@ module Steep
57
57
  main_thread = Thread.start do
58
58
  master.start()
59
59
  end
60
- main_thread.abort_on_exception = true
61
60
 
62
61
  initialize_id = request_id()
63
62
  client_writer.write(method: "initialize", id: initialize_id)
@@ -131,7 +130,7 @@ module Steep
131
130
  printer = DiagnosticPrinter.new(stdout: stdout, buffer: buffer)
132
131
 
133
132
  diagnostics = response[:params][:diagnostics]
134
- diagnostics.filter! {|d| keep_diagnostic?(d) }
133
+ diagnostics.filter! {|d| keep_diagnostic?(d, severity_level: severity_level) }
135
134
 
136
135
  unless diagnostics.empty?
137
136
  diagnostics.each do |diagnostic|
@@ -157,7 +156,13 @@ module Steep
157
156
  main_thread.join
158
157
  rescue Interrupt
159
158
  master.kill
160
- main_thread.join
159
+ begin
160
+ main_thread.join
161
+ rescue
162
+ master.each_worker do |worker|
163
+ worker.kill(force: true)
164
+ end
165
+ end
161
166
  end
162
167
 
163
168
  0