steep 1.8.0.dev.2 → 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 (70) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +33 -0
  3. data/bin/mem_graph.rb +67 -0
  4. data/bin/mem_prof.rb +102 -0
  5. data/bin/stackprof_test.rb +19 -0
  6. data/bin/steep-check.rb +251 -0
  7. data/lib/steep/annotation_parser.rb +1 -1
  8. data/lib/steep/ast/builtin.rb +5 -5
  9. data/lib/steep/ast/node/type_application.rb +7 -6
  10. data/lib/steep/ast/types/any.rb +1 -9
  11. data/lib/steep/ast/types/boolean.rb +8 -16
  12. data/lib/steep/ast/types/bot.rb +2 -10
  13. data/lib/steep/ast/types/class.rb +1 -13
  14. data/lib/steep/ast/types/factory.rb +101 -85
  15. data/lib/steep/ast/types/instance.rb +1 -13
  16. data/lib/steep/ast/types/intersection.rb +8 -15
  17. data/lib/steep/ast/types/literal.rb +2 -8
  18. data/lib/steep/ast/types/logic.rb +3 -24
  19. data/lib/steep/ast/types/name.rb +5 -16
  20. data/lib/steep/ast/types/nil.rb +3 -12
  21. data/lib/steep/ast/types/proc.rb +4 -13
  22. data/lib/steep/ast/types/record.rb +21 -12
  23. data/lib/steep/ast/types/self.rb +1 -13
  24. data/lib/steep/ast/types/shared_instance.rb +11 -0
  25. data/lib/steep/ast/types/top.rb +1 -9
  26. data/lib/steep/ast/types/tuple.rb +4 -10
  27. data/lib/steep/ast/types/union.rb +10 -15
  28. data/lib/steep/ast/types/var.rb +4 -13
  29. data/lib/steep/ast/types/void.rb +2 -10
  30. data/lib/steep/diagnostic/ruby.rb +4 -4
  31. data/lib/steep/drivers/check.rb +11 -14
  32. data/lib/steep/drivers/checkfile.rb +8 -10
  33. data/lib/steep/drivers/stats.rb +17 -13
  34. data/lib/steep/drivers/utils/driver_helper.rb +24 -3
  35. data/lib/steep/drivers/watch.rb +3 -3
  36. data/lib/steep/interface/builder.rb +162 -138
  37. data/lib/steep/interface/method_type.rb +12 -20
  38. data/lib/steep/interface/shape.rb +66 -10
  39. data/lib/steep/interface/substitution.rb +2 -0
  40. data/lib/steep/interface/type_param.rb +20 -7
  41. data/lib/steep/located_value.rb +20 -0
  42. data/lib/steep/server/change_buffer.rb +5 -7
  43. data/lib/steep/server/custom_methods.rb +61 -0
  44. data/lib/steep/server/delay_queue.rb +8 -1
  45. data/lib/steep/server/interaction_worker.rb +10 -5
  46. data/lib/steep/server/lsp_formatter.rb +8 -6
  47. data/lib/steep/server/master.rb +193 -140
  48. data/lib/steep/server/type_check_worker.rb +18 -19
  49. data/lib/steep/server/work_done_progress.rb +64 -0
  50. data/lib/steep/services/completion_provider.rb +24 -22
  51. data/lib/steep/services/goto_service.rb +3 -2
  52. data/lib/steep/services/hover_provider/ruby.rb +7 -6
  53. data/lib/steep/services/signature_help_provider.rb +7 -6
  54. data/lib/steep/services/signature_service.rb +1 -1
  55. data/lib/steep/services/type_check_service.rb +3 -3
  56. data/lib/steep/signature/validator.rb +17 -20
  57. data/lib/steep/subtyping/check.rb +105 -55
  58. data/lib/steep/subtyping/constraints.rb +11 -15
  59. data/lib/steep/type_construction.rb +100 -100
  60. data/lib/steep/type_inference/block_params.rb +6 -6
  61. data/lib/steep/type_inference/logic_type_interpreter.rb +11 -7
  62. data/lib/steep/type_inference/method_call.rb +3 -3
  63. data/lib/steep/type_inference/method_params.rb +1 -1
  64. data/lib/steep/type_inference/send_args.rb +1 -1
  65. data/lib/steep/typing.rb +158 -102
  66. data/lib/steep/version.rb +1 -1
  67. data/lib/steep.rb +28 -3
  68. data/steep.gemspec +2 -2
  69. metadata +16 -9
  70. data/lib/steep/type_inference/context_array.rb +0 -112
@@ -2,16 +2,14 @@ module Steep
2
2
  module AST
3
3
  module Types
4
4
  class Proc
5
- attr_reader :location
6
5
  attr_reader :type
7
6
  attr_reader :self_type
8
7
  attr_reader :block
9
8
 
10
- def initialize(type:, block:, self_type:, location: type.location)
9
+ def initialize(type:, block:, self_type:)
11
10
  @type = type
12
11
  @block = block
13
12
  @self_type = self_type
14
- @location = location
15
13
  end
16
14
 
17
15
  def ==(other)
@@ -28,8 +26,7 @@ module Steep
28
26
  self.class.new(
29
27
  type: type.subst(s),
30
28
  block: block&.subst(s),
31
- self_type: self_type&.subst(s),
32
- location: location
29
+ self_type: self_type&.subst(s)
33
30
  )
34
31
  end
35
32
 
@@ -70,16 +67,11 @@ module Steep
70
67
  [0] + level_of_children(children)
71
68
  end
72
69
 
73
- def with_location(new_location)
74
- self.class.new(location: new_location, block: block, type: type, self_type: self_type)
75
- end
76
-
77
70
  def map_type(&block)
78
71
  self.class.new(
79
72
  type: type.map_type(&block),
80
73
  block: self.block&.map_type(&block),
81
- self_type: self_type ? yield(self_type) : nil,
82
- location: location
74
+ self_type: self_type ? yield(self_type) : nil
83
75
  )
84
76
  end
85
77
 
@@ -99,8 +91,7 @@ module Steep
99
91
 
100
92
  def back_type
101
93
  Name::Instance.new(name: Builtin::Proc.module_name,
102
- args: [],
103
- location: location)
94
+ args: [])
104
95
  end
105
96
 
106
97
  def block_required?
@@ -2,32 +2,37 @@ module Steep
2
2
  module AST
3
3
  module Types
4
4
  class Record
5
- attr_reader :location
6
- attr_reader :elements
5
+ attr_reader :elements, :required_keys
7
6
 
8
- def initialize(elements:, location: nil)
7
+ def initialize(elements:, required_keys:)
9
8
  @elements = elements
10
- @location = location
9
+ @required_keys = required_keys
11
10
  end
12
11
 
13
12
  def ==(other)
14
- other.is_a?(Record) && other.elements == elements
13
+ other.is_a?(Record) && other.elements == elements && other.required_keys == required_keys
15
14
  end
16
15
 
17
16
  def hash
18
- self.class.hash ^ elements.hash
17
+ self.class.hash ^ elements.hash ^ required_keys.hash
19
18
  end
20
19
 
21
20
  alias eql? ==
22
21
 
23
22
  def subst(s)
24
- self.class.new(location: location,
25
- elements: elements.transform_values {|type| type.subst(s) })
23
+ self.class.new(
24
+ elements: elements.transform_values {|type| type.subst(s) },
25
+ required_keys: required_keys
26
+ )
26
27
  end
27
28
 
28
29
  def to_s
29
30
  strings = elements.keys.sort.map do |key|
30
- "#{key.inspect} => #{elements[key]}"
31
+ if optional?(key)
32
+ "?#{key.inspect} => #{elements[key]}"
33
+ else
34
+ "#{key.inspect} => #{elements[key]}"
35
+ end
31
36
  end
32
37
  "{ #{strings.join(", ")} }"
33
38
  end
@@ -53,7 +58,7 @@ module Steep
53
58
  def map_type(&block)
54
59
  self.class.new(
55
60
  elements: elements.transform_values(&block),
56
- location: location
61
+ required_keys: required_keys
57
62
  )
58
63
  end
59
64
 
@@ -61,8 +66,12 @@ module Steep
61
66
  [0] + level_of_children(elements.values)
62
67
  end
63
68
 
64
- def with_location(new_location)
65
- self.class.new(elements: elements, location: new_location)
69
+ def required?(key)
70
+ required_keys.include?(key)
71
+ end
72
+
73
+ def optional?(key)
74
+ !required_keys.include?(key)
66
75
  end
67
76
  end
68
77
  end
@@ -2,15 +2,7 @@ module Steep
2
2
  module AST
3
3
  module Types
4
4
  class Self
5
- attr_reader :location
6
-
7
- def initialize(location: nil)
8
- @location = location
9
- end
10
-
11
- def self.instance
12
- @instance ||= new()
13
- end
5
+ extend SharedInstance
14
6
 
15
7
  def ==(other)
16
8
  other.is_a?(Self)
@@ -45,10 +37,6 @@ module Steep
45
37
  def level
46
38
  [0]
47
39
  end
48
-
49
- def with_location(new_location)
50
- self.class.new(location: new_location)
51
- end
52
40
  end
53
41
  end
54
42
  end
@@ -0,0 +1,11 @@
1
+ module Steep
2
+ module AST
3
+ module Types
4
+ module SharedInstance
5
+ def instance
6
+ @instance ||= new
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -2,11 +2,7 @@ module Steep
2
2
  module AST
3
3
  module Types
4
4
  class Top
5
- attr_reader :location
6
-
7
- def initialize(location: nil)
8
- @location = location
9
- end
5
+ extend SharedInstance
10
6
 
11
7
  def ==(other)
12
8
  other.is_a?(Top)
@@ -33,10 +29,6 @@ module Steep
33
29
  def level
34
30
  [2]
35
31
  end
36
-
37
- def with_location(new_location)
38
- self.class.new(location: new_location)
39
- end
40
32
  end
41
33
  end
42
34
  end
@@ -3,11 +3,9 @@ module Steep
3
3
  module Types
4
4
  class Tuple
5
5
  attr_reader :types
6
- attr_reader :location
7
6
 
8
- def initialize(types:, location: nil)
7
+ def initialize(types:)
9
8
  @types = types
10
- @location = location
11
9
  end
12
10
 
13
11
  def ==(other)
@@ -22,8 +20,7 @@ module Steep
22
20
  alias eql? ==
23
21
 
24
22
  def subst(s)
25
- self.class.new(location: location,
26
- types: types.map {|ty| ty.subst(s) })
23
+ self.class.new(types: types.map {|ty| ty.subst(s) })
27
24
  end
28
25
 
29
26
  def to_s
@@ -47,10 +44,7 @@ module Steep
47
44
  end
48
45
 
49
46
  def map_type(&block)
50
- Tuple.new(
51
- types: types.map(&block),
52
- location: location
53
- )
47
+ Tuple.new(types: types.map(&block))
54
48
  end
55
49
 
56
50
  def level
@@ -58,7 +52,7 @@ module Steep
58
52
  end
59
53
 
60
54
  def with_location(new_location)
61
- self.class.new(types: types, location: new_location)
55
+ self.class.new(types: types)
62
56
  end
63
57
  end
64
58
  end
@@ -3,15 +3,13 @@ module Steep
3
3
  module Types
4
4
  class Union
5
5
  attr_reader :types
6
- attr_reader :location
7
6
 
8
- def initialize(types:, location: nil)
7
+ def initialize(types:)
9
8
  @types = types
10
- @location = location
11
9
  end
12
10
 
13
- def self.build(types:, location: nil)
14
- return AST::Types::Bot.new if types.empty?
11
+ def self.build(types:)
12
+ return AST::Types::Bot.instance if types.empty?
15
13
  if types.size == 1
16
14
  return types.first || raise
17
15
  end
@@ -25,9 +23,9 @@ module Steep
25
23
  end.map do |type|
26
24
  case type
27
25
  when AST::Types::Any
28
- return AST::Types::Any.new(location: location)
26
+ return AST::Types::Any.instance()
29
27
  when AST::Types::Top
30
- return AST::Types::Top.new(location: location)
28
+ return AST::Types::Top.instance
31
29
  when AST::Types::Bot
32
30
  nil
33
31
  else
@@ -36,11 +34,11 @@ module Steep
36
34
  end.compact.uniq.yield_self do |tys|
37
35
  case tys.size
38
36
  when 0
39
- AST::Types::Bot.new
37
+ AST::Types::Bot.instance
40
38
  when 1
41
39
  tys.first || raise
42
40
  else
43
- new(types: tys, location: location)
41
+ new(types: tys)
44
42
  end
45
43
  end
46
44
  end
@@ -57,7 +55,7 @@ module Steep
57
55
  alias eql? ==
58
56
 
59
57
  def subst(s)
60
- self.class.build(location: location, types: types.map {|ty| ty.subst(s) })
58
+ self.class.build(types: types.map {|ty| ty.subst(s) })
61
59
  end
62
60
 
63
61
  def to_s
@@ -81,10 +79,7 @@ module Steep
81
79
  end
82
80
 
83
81
  def map_type(&block)
84
- Union.build(
85
- types: types.map(&block),
86
- location: location
87
- )
82
+ Union.build(types: types.map(&block))
88
83
  end
89
84
 
90
85
  include Helper::ChildrenLevel
@@ -94,7 +89,7 @@ module Steep
94
89
  end
95
90
 
96
91
  def with_location(new_location)
97
- self.class.new(types: types, location: new_location)
92
+ self.class.new(types: types)
98
93
  end
99
94
  end
100
95
  end
@@ -3,11 +3,9 @@ module Steep
3
3
  module Types
4
4
  class Var
5
5
  attr_reader :name
6
- attr_reader :location
7
6
 
8
- def initialize(name:, location: nil)
7
+ def initialize(name:)
9
8
  @name = name
10
- @location = location
11
9
  end
12
10
 
13
11
  def ==(other)
@@ -33,7 +31,7 @@ module Steep
33
31
  end
34
32
 
35
33
  def self.fresh(name, location: nil)
36
- new(name: fresh_name(name), location: location)
34
+ new(name: fresh_name(name))
37
35
  end
38
36
 
39
37
  def to_s
@@ -58,15 +56,8 @@ module Steep
58
56
  [0]
59
57
  end
60
58
 
61
- def update(name: self.name, location: self.location)
62
- self.class.new(
63
- name: name,
64
- location: location
65
- )
66
- end
67
-
68
- def with_location(new_location)
69
- update(location: new_location)
59
+ def update(name: self.name)
60
+ self.class.new(name: name)
70
61
  end
71
62
  end
72
63
  end
@@ -2,12 +2,8 @@ module Steep
2
2
  module AST
3
3
  module Types
4
4
  class Void
5
- attr_reader :location
6
-
7
- def initialize(location: nil)
8
- @location = location
9
- end
10
-
5
+ extend SharedInstance
6
+
11
7
  def ==(other)
12
8
  other.is_a?(Void)
13
9
  end
@@ -33,10 +29,6 @@ module Steep
33
29
  def level
34
30
  [0]
35
31
  end
36
-
37
- def with_location(new_location)
38
- self.class.new(location: new_location)
39
- end
40
32
  end
41
33
  end
42
34
  end
@@ -904,8 +904,8 @@ module Steep
904
904
  class UnexpectedTypeArgument < Base
905
905
  attr_reader :type_arg, :method_type
906
906
 
907
- def initialize(type_arg:, method_type:)
908
- super(node: nil, location: type_arg.location)
907
+ def initialize(type_arg:, method_type:, location:)
908
+ super(node: nil, location: location)
909
909
  @type_arg = type_arg
910
910
  @method_type = method_type
911
911
  end
@@ -932,8 +932,8 @@ module Steep
932
932
  class TypeArgumentMismatchError < Base
933
933
  attr_reader :type_argument, :type_parameter, :result
934
934
 
935
- def initialize(type_arg:, type_param:, result:)
936
- super(node: nil, location: type_arg.location)
935
+ def initialize(type_arg:, type_param:, result:, location:)
936
+ super(node: nil, location: location)
937
937
  @type_argument = type_arg
938
938
  @type_parameter = type_param
939
939
  @result = result
@@ -61,42 +61,39 @@ module Steep
61
61
 
62
62
  Steep.logger.info { "Initializing server" }
63
63
  initialize_id = request_id()
64
- client_writer.write({ method: :initialize, id: initialize_id, params: {} })
64
+ client_writer.write({ method: :initialize, id: initialize_id, params: DEFAULT_CLI_LSP_INITIALIZE_PARAMS })
65
65
  wait_for_response_id(reader: client_reader, id: initialize_id)
66
66
 
67
67
  request_guid = SecureRandom.uuid
68
68
  Steep.logger.info { "Starting type checking: #{request_guid}" }
69
- client_writer.write({ method: "$/typecheck", params: { guid: request_guid } })
69
+ client_writer.write(Server::CustomMethods::TypeCheck.request(request_guid, { guid: request_guid}))
70
70
 
71
71
  diagnostic_notifications = [] #: Array[LanguageServer::Protocol::Interface::PublishDiagnosticsParams]
72
72
  error_messages = [] #: Array[String]
73
- client_reader.read do |response|
73
+
74
+ response = wait_for_response_id(reader: client_reader, id: request_guid) do |message|
74
75
  case
75
- when response[:method] == "textDocument/publishDiagnostics"
76
- ds = response[:params][:diagnostics]
76
+ when message[:method] == "textDocument/publishDiagnostics"
77
+ ds = message[:params][:diagnostics]
77
78
  ds.select! {|d| keep_diagnostic?(d, severity_level: severity_level) }
78
79
  if ds.empty?
79
80
  stdout.print "."
80
81
  else
81
82
  stdout.print "F"
82
83
  end
83
- diagnostic_notifications << response[:params]
84
+ diagnostic_notifications << message[:params]
84
85
  stdout.flush
85
- when response[:method] == "window/showMessage"
86
+ when message[:method] == "window/showMessage"
86
87
  # Assuming ERROR message means unrecoverable error.
87
- message = response[:params]
88
+ message = message[:params]
88
89
  if message[:type] == LSP::Constant::MessageType::ERROR
89
90
  error_messages << message[:message]
90
91
  end
91
- when response[:method] == "$/progress"
92
- if response[:params][:token] == request_guid
93
- if response[:params][:value][:kind] == "end"
94
- break
95
- end
96
- end
97
92
  end
98
93
  end
99
94
 
95
+ Steep.logger.info { "Finished type checking: #{response.inspect}" }
96
+
100
97
  Steep.logger.info { "Shutting down..." }
101
98
 
102
99
  shutdown_exit(reader: client_reader, writer: client_writer)
@@ -125,7 +125,7 @@ module Steep
125
125
 
126
126
  Steep.logger.info { "Initializing server" }
127
127
  initialize_id = request_id()
128
- client_writer.write({ method: :initialize, id: initialize_id, params: {} })
128
+ client_writer.write({ method: :initialize, id: initialize_id, params: DEFAULT_CLI_LSP_INITIALIZE_PARAMS })
129
129
  wait_for_response_id(reader: client_reader, id: initialize_id)
130
130
 
131
131
  stdin_input.each do |path, content|
@@ -151,11 +151,12 @@ module Steep
151
151
  end
152
152
 
153
153
  ping_guid = master.fresh_request_id()
154
- client_writer.write({ method: "$/ping", id: ping_guid, params: {} })
154
+ client_writer.write({ method: "$/ping", id: ping_guid, params: {}})
155
155
  wait_for_response_id(reader: client_reader, id: ping_guid)
156
156
 
157
157
  request_guid = master.fresh_request_id()
158
- request = Server::Master::TypeCheckRequest.new(guid: request_guid)
158
+ progress = master.work_done_progress(request_guid)
159
+ request = Server::Master::TypeCheckRequest.new(guid: request_guid, progress: progress)
159
160
 
160
161
  target_paths.each do |path|
161
162
  request.code_paths << project.absolute_path(path)
@@ -164,12 +165,13 @@ module Steep
164
165
  request.signature_paths << project.absolute_path(path)
165
166
  end
166
167
 
167
- master.start_type_check(request, last_request: nil, start_progress: true)
168
+ master.start_type_check(request: request, last_request: nil, report_progress_threshold: 0)
168
169
 
169
170
  Steep.logger.info { "Starting type checking: #{request_guid}" }
170
171
 
171
172
  error_messages = [] #: Array[String]
172
173
  client_reader.read do |response|
174
+ Steep.logger.info { response.inspect }
173
175
  case
174
176
  when response[:method] == "textDocument/publishDiagnostics"
175
177
  params = response[:params]
@@ -188,12 +190,8 @@ module Steep
188
190
  if message[:type] == LSP::Constant::MessageType::ERROR
189
191
  error_messages << message[:message]
190
192
  end
191
- when response[:method] == "$/progress"
192
- if response[:params][:token] == request_guid
193
- if response[:params][:value][:kind] == "end"
194
- break
195
- end
196
- end
193
+ when response[:id] == request_guid
194
+ break
197
195
  end
198
196
  end
199
197
 
@@ -16,6 +16,7 @@ module Steep
16
16
  csv << ["Target", "File", "Status", "Typed calls", "Untyped calls", "All calls", "Typed %"]
17
17
  stats_result.each do |row|
18
18
  if row[:type] == "success"
19
+ # @type var row: Steep::Services::StatsCalculator::SuccessStats::json
19
20
  csv << [
20
21
  row[:target],
21
22
  row[:path],
@@ -30,6 +31,7 @@ module Steep
30
31
  end
31
32
  ]
32
33
  else
34
+ # @type var row: Steep::Services::StatsCalculator::ErrorStats::json
33
35
  csv << [
34
36
  row[:target],
35
37
  row[:path],
@@ -57,7 +59,8 @@ module Steep
57
59
  rows = [] #: Array[Array[untyped]]
58
60
  stats_result.sort_by {|row| row[:path] }.each do |row|
59
61
  if row[:type] == "success"
60
- rows << [
62
+ # @type var row: Steep::Services::StatsCalculator::SuccessStats::json
63
+ rows << [
61
64
  row[:target],
62
65
  row[:path] + " ",
63
66
  row[:type],
@@ -71,6 +74,7 @@ module Steep
71
74
  end
72
75
  ]
73
76
  else
77
+ # @type var row: Steep::Services::StatsCalculator::ErrorStats::json
74
78
  rows << [
75
79
  row[:target],
76
80
  row[:path],
@@ -150,27 +154,27 @@ module Steep
150
154
  end
151
155
 
152
156
  initialize_id = request_id()
153
- client_writer.write({ method: :initialize, id: initialize_id })
157
+ client_writer.write({ method: :initialize, id: initialize_id, params: DEFAULT_CLI_LSP_INITIALIZE_PARAMS })
154
158
  wait_for_response_id(reader: client_reader, id: initialize_id)
155
159
 
156
160
  typecheck_guid = SecureRandom.uuid
157
- client_writer.write({ method: "$/typecheck", params: { guid: typecheck_guid }})
161
+
162
+ master.job_queue << -> do
163
+ Steep.logger.info { "Type checking for stats..." }
164
+ progress = master.work_done_progress(typecheck_guid)
165
+ master.start_type_check(last_request: nil, progress: progress, include_unchanged: true, report_progress_threshold: 0)
166
+ end
158
167
  wait_for_message(reader: client_reader) do |message|
159
- message[:method] == "$/progress" &&
160
- message[:params][:token] == typecheck_guid &&
161
- message[:params][:value][:kind] == "end"
168
+ message[:id] == typecheck_guid
162
169
  end
163
170
 
171
+ Steep.logger.info { "Finished type checking for stats" }
172
+
164
173
  stats_id = request_id()
165
- client_writer.write(
166
- {
167
- id: stats_id,
168
- method: "workspace/executeCommand",
169
- params: { command: "steep/stats", arguments: _ = [] }
170
- })
174
+ client_writer.write(Server::CustomMethods::Stats.request(stats_id))
171
175
 
172
176
  stats_response = wait_for_response_id(reader: client_reader, id: stats_id)
173
- stats_result = stats_response[:result]
177
+ stats_result = stats_response[:result] #: Server::CustomMethods::Stats::result
174
178
 
175
179
  shutdown_exit(reader: client_reader, writer: client_writer)
176
180
  main_thread.join()
@@ -38,9 +38,28 @@ module Steep
38
38
  SecureRandom.alphanumeric(10)
39
39
  end
40
40
 
41
- def wait_for_response_id(reader:, id:, unknown_responses: :ignore)
42
- wait_for_message(reader: reader, unknown_messages: unknown_responses) do |response|
43
- response[:id] == id
41
+ def wait_for_response_id(reader:, id:, unknown_responses: nil, &block)
42
+ reader.read do |message|
43
+ Steep.logger.debug { "Received message waiting for #{id}: #{message.inspect}" }
44
+
45
+ response_id = message[:id]
46
+
47
+ if response_id == id
48
+ return message
49
+ end
50
+
51
+ if block
52
+ yield message
53
+ else
54
+ case unknown_responses
55
+ when :ignore, nil
56
+ # nop
57
+ when :log
58
+ Steep.logger.error { "Unexpected message: #{message.inspect}" }
59
+ when :raise
60
+ raise "Unexpected message: #{message.inspect}"
61
+ end
62
+ end
44
63
  end
45
64
  end
46
65
 
@@ -83,6 +102,8 @@ module Steep
83
102
  severity <= LanguageServer::Protocol::Constant::DiagnosticSeverity::INFORMATION
84
103
  end
85
104
  end
105
+
106
+ (DEFAULT_CLI_LSP_INITIALIZE_PARAMS = {}).freeze
86
107
  end
87
108
  end
88
109
  end
@@ -59,7 +59,7 @@ module Steep
59
59
  end
60
60
 
61
61
  initialize_id = request_id()
62
- client_writer.write(method: "initialize", id: initialize_id)
62
+ client_writer.write(method: "initialize", id: initialize_id, params: DEFAULT_CLI_LSP_INITIALIZE_PARAMS)
63
63
  wait_for_response_id(reader: client_reader, id: initialize_id)
64
64
 
65
65
  Steep.logger.info "Watching #{dirs.join(", ")}..."
@@ -112,7 +112,7 @@ module Steep
112
112
  end
113
113
  end
114
114
 
115
- client_writer.write(method: "$/typecheck", params: { guid: nil })
115
+ client_writer.write(Server::CustomMethods::TypeCheck.request(SecureRandom.uuid, { guid: nil }))
116
116
 
117
117
  stdout.puts Rainbow("done!").bold
118
118
  end.tap(&:start)
@@ -120,7 +120,7 @@ module Steep
120
120
  begin
121
121
  stdout.puts Rainbow("👀 Watching directories, Ctrl-C to stop.").bold
122
122
 
123
- client_writer.write(method: "$/typecheck", params: { guid: nil })
123
+ client_writer.write(Server::CustomMethods::TypeCheck.request(SecureRandom.uuid, { guid: nil }))
124
124
 
125
125
  client_reader.read do |response|
126
126
  case response[:method]