steep 1.5.3 → 1.6.0.pre.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby-windows.yml +1 -2
  3. data/.github/workflows/ruby.yml +1 -2
  4. data/CHANGELOG.md +35 -0
  5. data/Gemfile +3 -1
  6. data/Gemfile.lock +36 -9
  7. data/gemfile_steep/Gemfile.lock +3 -3
  8. data/lib/steep/ast/types/logic.rb +6 -0
  9. data/lib/steep/cli.rb +39 -19
  10. data/lib/steep/interface/builder.rb +9 -0
  11. data/lib/steep/path_helper.rb +2 -0
  12. data/lib/steep/server/change_buffer.rb +9 -0
  13. data/lib/steep/server/delay_queue.rb +41 -0
  14. data/lib/steep/server/interaction_worker.rb +4 -2
  15. data/lib/steep/server/master.rb +106 -10
  16. data/lib/steep/server/type_check_worker.rb +10 -3
  17. data/lib/steep/services/completion_provider.rb +1 -1
  18. data/lib/steep/services/stats_calculator.rb +2 -2
  19. data/lib/steep/services/type_name_completion.rb +86 -15
  20. data/lib/steep/signature/validator.rb +9 -2
  21. data/lib/steep/subtyping/check.rb +24 -18
  22. data/lib/steep/type_construction.rb +59 -17
  23. data/lib/steep/type_inference/logic_type_interpreter.rb +26 -0
  24. data/lib/steep/type_inference/method_params.rb +1 -1
  25. data/lib/steep/version.rb +1 -1
  26. data/lib/steep.rb +1 -3
  27. data/sig/shims/language-server_protocol.rbs +12 -0
  28. data/sig/steep/ast/types/logic.rbs +5 -0
  29. data/sig/steep/ast/types.rbs +1 -1
  30. data/sig/steep/cli.rbs +2 -0
  31. data/sig/steep/diagnostic/ruby.rbs +7 -7
  32. data/sig/steep/server/change_buffer.rbs +4 -0
  33. data/sig/steep/server/delay_queue.rbs +37 -0
  34. data/sig/steep/server/master.rbs +4 -0
  35. data/sig/steep/services/stats_calculator.rbs +30 -6
  36. data/sig/steep/services/type_name_completion.rbs +13 -0
  37. data/sig/steep/signature/validator.rbs +5 -0
  38. data/sig/steep/subtyping/check.rbs +1 -1
  39. data/sig/steep/subtyping/relation.rbs +11 -1
  40. data/sig/steep/subtyping/result.rbs +1 -1
  41. data/sig/steep/type_construction.rbs +1 -1
  42. data/smoke/block/test_expectations.yml +10 -14
  43. data/smoke/enumerator/test_expectations.yml +10 -10
  44. data/smoke/integer/test_expectations.yml +5 -16
  45. data/smoke/regression/hello world.rb +1 -0
  46. data/smoke/regression/test_expectations.yml +12 -0
  47. data/steep.gemspec +1 -1
  48. metadata +8 -7
  49. data/lib/steep/shims/filter_map.rb +0 -30
  50. data/lib/steep/shims/symbol_start_with.rb +0 -18
@@ -70,8 +70,15 @@ module Steep
70
70
  when "initialize"
71
71
  load_files(project: project, commandline_args: commandline_args)
72
72
  writer.write({ id: request[:id], result: nil})
73
+
73
74
  when "textDocument/didChange"
74
75
  collect_changes(request)
76
+
77
+ when "$/file/reset"
78
+ uri = request[:params][:uri]
79
+ text = request[:params][:content]
80
+ reset_change(uri: uri, text: text)
81
+
75
82
  when "workspace/symbol"
76
83
  query = request[:params][:query]
77
84
  queue << WorkspaceSymbolJob.new(id: request[:id], query: query)
@@ -165,7 +172,7 @@ module Steep
165
172
  writer.write(
166
173
  method: :"textDocument/publishDiagnostics",
167
174
  params: LSP::Interface::PublishDiagnosticsParams.new(
168
- uri: Steep::PathHelper.to_uri(job.path),
175
+ uri: Steep::PathHelper.to_uri(job.path).to_s,
169
176
  diagnostics: diagnostics.map {|diagnostic| formatter.format(diagnostic) }.uniq
170
177
  )
171
178
  )
@@ -183,7 +190,7 @@ module Steep
183
190
  writer.write(
184
191
  method: :"textDocument/publishDiagnostics",
185
192
  params: LSP::Interface::PublishDiagnosticsParams.new(
186
- uri: Steep::PathHelper.to_uri(job.path),
193
+ uri: Steep::PathHelper.to_uri(job.path).to_s,
187
194
  diagnostics: diagnostics.map {|diagnostic| formatter.format(diagnostic) }.uniq.compact
188
195
  )
189
196
  )
@@ -202,7 +209,7 @@ module Steep
202
209
  writer.write(
203
210
  method: :"textDocument/publishDiagnostics",
204
211
  params: LSP::Interface::PublishDiagnosticsParams.new(
205
- uri: Steep::PathHelper.to_uri(job.path),
212
+ uri: Steep::PathHelper.to_uri(job.path).to_s,
206
213
  diagnostics: diagnostics.map {|diagnostic| formatter.format(diagnostic) }.uniq.compact
207
214
  )
208
215
  )
@@ -115,7 +115,7 @@ module Steep
115
115
  when RBS::Environment::ClassAliasEntry, RBS::Environment::ModuleAliasEntry
116
116
  entry.decl
117
117
  else
118
- raise
118
+ raise "absolute_type_name=#{absolute_type_name}, relative_type_name=#{relative_type_name}"
119
119
  end
120
120
  else
121
121
  raise
@@ -1,7 +1,7 @@
1
1
  module Steep
2
2
  module Services
3
3
  class StatsCalculator
4
- SuccessStats = Struct.new(:target, :path, :typed_calls_count, :untyped_calls_count, :error_calls_count, keyword_init: true) do
4
+ class SuccessStats < Struct.new(:target, :path, :typed_calls_count, :untyped_calls_count, :error_calls_count, keyword_init: true)
5
5
  def as_json
6
6
  {
7
7
  type: "success",
@@ -14,7 +14,7 @@ module Steep
14
14
  }
15
15
  end
16
16
  end
17
- ErrorStats = Struct.new(:target, :path, keyword_init: true) do
17
+ class ErrorStats < Struct.new(:target, :path, keyword_init: true)
18
18
  def as_json
19
19
  {
20
20
  type: "error",
@@ -31,15 +31,20 @@ module Steep
31
31
 
32
32
  case prefix
33
33
  when /\A((::\w+[A-Z])+(::)?)/
34
- NamespacePrefix.new(RBS::Namespace.parse($1.reverse), $1.size)
34
+ namespace = $1 or raise
35
+ NamespacePrefix.new(RBS::Namespace.parse(namespace.reverse), namespace.size)
35
36
  when /\A::/
36
37
  NamespacePrefix.new(RBS::Namespace.root, 2)
37
38
  when /\A(\w*[A-Za-z_])((::\w+[A-Z])+(::)?)/
38
- NamespacedIdentPrefix.new(RBS::Namespace.parse($2.reverse), $1.reverse, $1.size + $2.size)
39
+ namespace = $1 or raise
40
+ identifier = $2 or raise
41
+ NamespacedIdentPrefix.new(RBS::Namespace.parse(identifier.reverse), namespace.reverse, namespace.size + identifier.size)
39
42
  when /\A(\w*[A-Za-z_])::/
40
- NamespacedIdentPrefix.new(RBS::Namespace.root, $1.reverse, $1.size + 2)
43
+ namespace = $1 or raise
44
+ NamespacedIdentPrefix.new(RBS::Namespace.root, namespace.reverse, namespace.size + 2)
41
45
  when /\A(\w*[A-Za-z_])/
42
- RawIdentPrefix.new($1.reverse)
46
+ identifier = $1 or raise
47
+ RawIdentPrefix.new(identifier.reverse)
43
48
  end
44
49
  end
45
50
  end
@@ -92,36 +97,97 @@ module Steep
92
97
  if block
93
98
  env = self.env
94
99
 
100
+ table = {} #: Hash[RBS::Namespace, Array[RBS::TypeName]]
101
+ env.class_decls.each_key do |type_name|
102
+ yield(type_name)
103
+ (table[type_name.namespace] ||= []) << type_name
104
+ end
105
+ env.type_alias_decls.each_key do |type_name|
106
+ yield(type_name)
107
+ (table[type_name.namespace] ||= []) << type_name
108
+ end
109
+ env.interface_decls.each_key do |type_name|
110
+ yield(type_name)
111
+ (table[type_name.namespace] ||= []) << type_name
112
+ end
113
+ env.class_alias_decls.each_key do |type_name|
114
+ yield(type_name)
115
+ (table[type_name.namespace] ||= []) << type_name
116
+ end
117
+
118
+ env.class_alias_decls.each_key do |alias_name|
119
+ normalized_name = env.normalize_module_name?(alias_name) or next
120
+ each_type_name_under(alias_name, normalized_name, table: table, &block)
121
+ end
122
+
123
+ resolve_pairs = [] #: Array[[RBS::TypeName, RBS::TypeName]]
124
+
95
125
  map.instance_eval do
96
126
  @map.each_key do |name|
97
127
  relative_name = RBS::TypeName.new(name: name, namespace: RBS::Namespace.empty)
98
128
  if absolute_name = resolve?(relative_name)
99
129
  if env.type_name?(absolute_name)
100
130
  # Yields only if the relative type name resolves to existing absolute type name
101
- yield relative_name
131
+ resolve_pairs << [relative_name, absolute_name]
102
132
  end
103
133
  end
104
134
  end
105
135
  end
106
- env.class_decls.each_key(&block)
107
- env.class_alias_decls.each_key(&block)
108
- env.type_alias_decls.each_key(&block)
109
- env.interface_decls.each_key(&block)
136
+
137
+ resolve_pairs.each do |use_name, absolute_name|
138
+ yield use_name
139
+ each_type_name_under(use_name, absolute_name, table: table, &block)
140
+ end
110
141
  else
111
142
  enum_for :each_type_name
112
143
  end
113
144
  end
114
145
 
146
+ def each_type_name_under(module_name, normalized_name, table:, &block)
147
+ if children = table.fetch(normalized_name.to_namespace, nil)
148
+ module_namespace = module_name.to_namespace
149
+
150
+ children.each do |normalized_child_name|
151
+ child_name = RBS::TypeName.new(namespace: module_namespace, name: normalized_child_name.name)
152
+
153
+ yield child_name
154
+
155
+ if normalized_child_name.class?
156
+ each_type_name_under(child_name, env.normalize_module_name(normalized_child_name), table: table, &block)
157
+ end
158
+ end
159
+ end
160
+ end
161
+
162
+ def resolve_used_name(name)
163
+ return nil if name.absolute?
164
+
165
+ case
166
+ when resolved = map.resolve?(name)
167
+ resolved
168
+ when name.namespace.empty?
169
+ nil
170
+ else
171
+ if resolved_parent = resolve_used_name(name.namespace.to_type_name)
172
+ resolved_name = RBS::TypeName.new(namespace: resolved_parent.to_namespace, name: name.name)
173
+ if env.normalize_type_name?(resolved_name)
174
+ resolved_name
175
+ end
176
+ end
177
+ end
178
+ end
179
+
115
180
  def resolve_name_in_context(name)
116
- if resolved_name = map.resolve?(name)
181
+ if resolved_name = resolve_used_name(name)
117
182
  return [resolved_name, name]
118
183
  end
119
184
 
120
185
  name.absolute? or raise
186
+ normalized_name = env.normalize_type_name?(name) or raise "Cannot normalize given type name `#{name}`"
121
187
 
122
188
  name.namespace.path.reverse_each.inject(RBS::TypeName.new(namespace: RBS::Namespace.empty, name: name.name)) do |relative_name, component|
123
189
  if type_name_resolver.resolve(relative_name, context: context) == name
124
- return [name, relative_name]
190
+ return [normalized_name, relative_name]
125
191
  end
126
192
 
127
193
  RBS::TypeName.new(
@@ -130,10 +196,10 @@ module Steep
130
196
  )
131
197
  end
132
198
 
133
- if type_name_resolver.resolve(name.relative!, context: context) == name && !map.resolve?(name.relative!)
134
- [name, name.relative!]
199
+ if type_name_resolver.resolve(name.relative!, context: context) == name && !resolve_used_name(name.relative!)
200
+ [normalized_name, name.relative!]
135
201
  else
136
- [name, name]
202
+ [normalized_name, name]
137
203
  end
138
204
  end
139
205
 
@@ -144,7 +210,12 @@ module Steep
144
210
  type_name.split.any? {|sym| sym.to_s.downcase.include?(prefix.ident.downcase) }
145
211
  end
146
212
  when Prefix::NamespacedIdentPrefix
147
- absolute_namespace = type_name_resolver.resolve(prefix.namespace.to_type_name, context: context)&.to_namespace || prefix.namespace
213
+ absolute_namespace =
214
+ if prefix.namespace.empty?
215
+ RBS::Namespace.root
216
+ else
217
+ type_name_resolver.resolve(prefix.namespace.to_type_name, context: context)&.to_namespace || prefix.namespace
218
+ end
148
219
 
149
220
  each_type_name.filter do|name|
150
221
  name.namespace == absolute_namespace &&
@@ -112,10 +112,11 @@ module Steep
112
112
  type.args
113
113
  ]
114
114
  when RBS::Types::Alias
115
- entry = env.type_alias_decls[type.name]
115
+ type_name = env.normalize_type_name?(type.name) or return
116
+ entry = env.type_alias_decls[type_name]
116
117
 
117
118
  [
118
- type.name,
119
+ type_name,
119
120
  entry.decl.type_params,
120
121
  type.args
121
122
  ]
@@ -520,6 +521,12 @@ module Steep
520
521
  def validate_one_alias(name, entry = env.type_alias_decls[name])
521
522
  rescue_validation_errors(name) do
522
523
  Steep.logger.debug "Validating alias `#{name}`..."
524
+
525
+ unless name.namespace.empty?
526
+ outer = name.namespace.to_type_name
527
+ builder.validate_type_name(outer, entry.decl.location&.aref(:name))
528
+ end
529
+
523
530
  upper_bounds = entry.decl.type_params.each.with_object({}) do |param, bounds|
524
531
  bounds[param.name] = factory.type_opt(param.upper_bound)
525
532
  end
@@ -79,11 +79,11 @@ module Steep
79
79
  end
80
80
 
81
81
  def instance_type
82
- @instance_type
82
+ @instance_type || AST::Types::Instance.instance
83
83
  end
84
84
 
85
85
  def class_type
86
- @class_type
86
+ @class_type || AST::Types::Class.instance
87
87
  end
88
88
 
89
89
  def constraints
@@ -193,7 +193,7 @@ module Steep
193
193
  bounds = cache_bounds(relation)
194
194
  fvs = relation.sub_type.free_variables + relation.super_type.free_variables
195
195
  cached = cache[relation, @self_type, @instance_type, @class_type, bounds]
196
- if cached && fvs.none? {|var| constraints.unknown?(var) }
196
+ if cached && fvs.none? {|var| var.is_a?(Symbol) && constraints.unknown?(var) }
197
197
  cached
198
198
  else
199
199
  if assumptions.member?(relation)
@@ -212,7 +212,8 @@ module Steep
212
212
 
213
213
  def cache_bounds(relation)
214
214
  vars = relation.sub_type.free_variables + relation.super_type.free_variables
215
- vars.each.with_object({}) do |var, hash|
215
+ vars.each.with_object({}) do |var, hash| #$ Hash[Symbol, AST::Types::t]
216
+ next unless var.is_a?(Symbol)
216
217
  if upper_bound = variable_upper_bound(var)
217
218
  hash[var] = upper_bound
218
219
  end
@@ -232,7 +233,7 @@ module Steep
232
233
  when AST::Types::Literal
233
234
  type.value == true
234
235
  else
235
- AST::Builtin::TrueClass.instance_type?(type)
236
+ AST::Builtin::TrueClass.instance_type?(type) ? true : false
236
237
  end
237
238
  end
238
239
 
@@ -241,7 +242,7 @@ module Steep
241
242
  when AST::Types::Literal
242
243
  type.value == false
243
244
  else
244
- AST::Builtin::FalseClass.instance_type?(type)
245
+ AST::Builtin::FalseClass.instance_type?(type) ? true : false
245
246
  end
246
247
  end
247
248
 
@@ -410,7 +411,7 @@ module Steep
410
411
  class_type: class_type,
411
412
  variable_bounds: variable_upper_bounds
412
413
  )
413
- ) or raise
414
+ ) or return Failure(relation, Result::Failure::UnknownPairError.new(relation: relation))
414
415
  }
415
416
  )
416
417
  end
@@ -492,7 +493,7 @@ module Steep
492
493
  Failure(relation, Result::Failure::UnknownPairError.new(relation: relation))
493
494
  end
494
495
 
495
- when relation.sub_type.is_a?(AST::Types::Tuple) && AST::Builtin::Array.instance_type?(relation.super_type)
496
+ when relation.sub_type.is_a?(AST::Types::Tuple) && (super_type = AST::Builtin::Array.instance_type?(relation.super_type))
496
497
  Expand(relation) do
497
498
  tuple_element_type =
498
499
  AST::Types::Union.build(
@@ -500,7 +501,7 @@ module Steep
500
501
  location: relation.sub_type.location
501
502
  )
502
503
 
503
- check_type(Relation.new(sub_type: tuple_element_type, super_type: relation.super_type.args[0]))
504
+ check_type(Relation.new(sub_type: tuple_element_type, super_type: super_type.args[0]))
504
505
  end
505
506
 
506
507
  when relation.sub_type.is_a?(AST::Types::Record) && relation.super_type.is_a?(AST::Types::Record)
@@ -549,9 +550,7 @@ module Steep
549
550
  end
550
551
 
551
552
  when relation.super_type.is_a?(AST::Types::Nil) && AST::Builtin::NilClass.instance_type?(relation.sub_type)
552
- Success(relation)
553
-
554
- when relation.sub_type.is_a?(AST::Types::Nil) && AST::Builtin::NilClass.instance_type?(relation.super_type)
553
+ # NilClass <: nil
555
554
  Success(relation)
556
555
 
557
556
  when relation.sub_type.is_a?(AST::Types::Literal)
@@ -742,10 +741,17 @@ module Steep
742
741
  args = sub_type.type_params.map {|type_param| AST::Types::Var.fresh(type_param.name) }
743
742
  args.each {|arg| constraints.unknown!(arg.name) }
744
743
 
745
- upper_bounds = {}
746
- relations = [] #: Array[Relation]
744
+ upper_bounds = {} #: Hash[Symbol, AST::Types::t]
745
+ relations = [] #: Array[Relation[AST::Types::t]]
747
746
 
748
747
  args.zip(sub_type.type_params, super_type.type_params).each do |arg, sub_param, sup_param|
748
+ # @type var arg: AST::Types::Var
749
+ # @type var sub_param: Interface::TypeParam?
750
+ # @type var super_param: Interface::TypeParam?
751
+
752
+ sub_param or raise
753
+ sup_param or raise
754
+
749
755
  sub_ub = sub_param.upper_bound
750
756
  sup_ub = sup_param.upper_bound
751
757
 
@@ -927,7 +933,7 @@ module Steep
927
933
 
928
934
  sub_params, super_params = relation
929
935
 
930
- pairs = []
936
+ pairs = [] #: Array[[AST::Types::t, AST::Types::t]]
931
937
 
932
938
  sub_flat = sub_params.flat_unnamed_params
933
939
  sup_flat = super_params.flat_unnamed_params
@@ -939,7 +945,7 @@ module Steep
939
945
  return failure unless sub_params.rest
940
946
 
941
947
  while sub_flat.size > 0
942
- sub_type = sub_flat.shift
948
+ sub_type = sub_flat.shift or raise
943
949
  sup_type = sup_flat.shift
944
950
 
945
951
  if sup_type
@@ -955,7 +961,7 @@ module Steep
955
961
 
956
962
  when sub_params.rest
957
963
  while sub_flat.size > 0
958
- sub_type = sub_flat.shift
964
+ sub_type = sub_flat.shift or raise
959
965
  sup_type = sup_flat.shift
960
966
 
961
967
  if sup_type
@@ -972,7 +978,7 @@ module Steep
972
978
  end
973
979
  when sub_params.required.size + sub_params.optional.size >= super_params.required.size + super_params.optional.size
974
980
  while sub_flat.size > 0
975
- sub_type = sub_flat.shift
981
+ sub_type = sub_flat.shift or raise
976
982
  sup_type = sup_flat.shift
977
983
 
978
984
  if sup_type
@@ -1305,29 +1305,39 @@ module Steep
1305
1305
  var = node.children[0]
1306
1306
  rhs = node.children[1]
1307
1307
 
1308
- var_type = context.type_env[var]
1308
+ if SPECIAL_LVAR_NAMES.include?(var)
1309
+ synthesize(rhs)
1310
+ add_typing(node, type: AST::Builtin.any_type)
1311
+ else
1312
+ var_type = context.type_env[var]
1309
1313
 
1310
- if var_type
1311
- type, constr = check(rhs, var_type) do |expected_type, actual_type, result|
1312
- typing.add_error(
1313
- Diagnostic::Ruby::IncompatibleAssignment.new(
1314
- node: node,
1315
- lhs_type: expected_type,
1316
- rhs_type: actual_type,
1317
- result: result
1314
+ if var_type
1315
+ type, constr = check(rhs, var_type) do |expected_type, actual_type, result|
1316
+ typing.add_error(
1317
+ Diagnostic::Ruby::IncompatibleAssignment.new(
1318
+ node: node,
1319
+ lhs_type: expected_type,
1320
+ rhs_type: actual_type,
1321
+ result: result
1322
+ )
1318
1323
  )
1319
- )
1324
+ end
1325
+ else
1326
+ type, constr = synthesize(rhs)
1320
1327
  end
1321
- else
1322
- type, constr = synthesize(rhs)
1323
- end
1324
1328
 
1325
- constr.add_typing(node, type: type)
1329
+ constr.add_typing(node, type: type)
1330
+ end
1326
1331
  end
1327
1332
 
1328
1333
  when :restarg
1329
1334
  yield_self do
1330
1335
  var = node.children[0]
1336
+
1337
+ if SPECIAL_LVAR_NAMES.include?(var)
1338
+ return add_typing(node, type: AST::Builtin.any_type)
1339
+ end
1340
+
1331
1341
  type = context.type_env[var]
1332
1342
 
1333
1343
  unless type
@@ -1344,6 +1354,11 @@ module Steep
1344
1354
  when :kwrestarg
1345
1355
  yield_self do
1346
1356
  var = node.children[0]
1357
+
1358
+ if SPECIAL_LVAR_NAMES.include?(var)
1359
+ return add_typing(node, type: AST::Builtin.any_type)
1360
+ end
1361
+
1347
1362
  type = context.type_env[var]
1348
1363
  unless type
1349
1364
  if context.method_context&.method_type
@@ -3046,6 +3061,7 @@ module Steep
3046
3061
  end
3047
3062
  else
3048
3063
  parent_type, constr = synthesize(parent_node).to_ary
3064
+ parent_type = expand_self(parent_type)
3049
3065
  parent_type = deep_expand_alias(parent_type)
3050
3066
 
3051
3067
  case parent_type
@@ -3284,7 +3300,14 @@ module Steep
3284
3300
 
3285
3301
  if call && constr
3286
3302
  case method_name.to_s
3287
- when "[]=", /\w=\Z/
3303
+ when "[]="
3304
+ if test_send_node(node) {|_, _, _, loc| !loc.dot }
3305
+ last_arg = arguments.last or raise
3306
+ if typing.has_type?(last_arg)
3307
+ call = call.with_return_type(typing.type_of(node: last_arg))
3308
+ end
3309
+ end
3310
+ when /\w=\Z/
3288
3311
  last_arg = arguments.last or raise
3289
3312
  if typing.has_type?(last_arg)
3290
3313
  call = call.with_return_type(typing.type_of(node: last_arg))
@@ -3292,7 +3315,7 @@ module Steep
3292
3315
  end
3293
3316
 
3294
3317
  if call.is_a?(TypeInference::MethodCall::Typed)
3295
- if (pure_call, type = constr.context.type_env.pure_method_calls[node])
3318
+ if (pure_call, type = constr.context.type_env.pure_method_calls.fetch(node, nil))
3296
3319
  if type
3297
3320
  call = pure_call.update(node: node, return_type: type)
3298
3321
  constr.add_typing(node, type: call.return_type)
@@ -3345,12 +3368,14 @@ module Steep
3345
3368
  method_name: method_name,
3346
3369
  method_types: method.method_types
3347
3370
  )
3371
+ decls = method.method_types.each_with_object(Set[]) {|type, decls| decls.merge(type.method_decls) }
3348
3372
  call = TypeInference::MethodCall::Error.new(
3349
3373
  node: node,
3350
3374
  context: context.call_context,
3351
3375
  method_name: method_name,
3352
3376
  receiver_type: receiver_type,
3353
- errors: errors
3377
+ errors: errors,
3378
+ method_decls: decls
3354
3379
  )
3355
3380
  end
3356
3381
 
@@ -3665,6 +3690,23 @@ module Steep
3665
3690
  end
3666
3691
  end
3667
3692
 
3693
+ non_arity_errors = fails.reject do |call, _|
3694
+ if call.is_a?(TypeInference::MethodCall::Error)
3695
+ call.errors.any? do |error|
3696
+ error.is_a?(Diagnostic::Ruby::UnexpectedBlockGiven) ||
3697
+ error.is_a?(Diagnostic::Ruby::RequiredBlockMissing) ||
3698
+ error.is_a?(Diagnostic::Ruby::UnexpectedPositionalArgument) ||
3699
+ error.is_a?(Diagnostic::Ruby::InsufficientPositionalArguments) ||
3700
+ error.is_a?(Diagnostic::Ruby::UnexpectedKeywordArgument) ||
3701
+ error.is_a?(Diagnostic::Ruby::InsufficientKeywordArguments)
3702
+ end
3703
+ end
3704
+ end
3705
+
3706
+ unless non_arity_errors.empty?
3707
+ fails = non_arity_errors
3708
+ end
3709
+
3668
3710
  if fails.one?
3669
3711
  call, constr = fails[0]
3670
3712
 
@@ -367,6 +367,32 @@ module Steep
367
367
  [truthy_result, falsy_result]
368
368
  end
369
369
  end
370
+
371
+ when AST::Types::Logic::ArgIsAncestor
372
+ if receiver && (arg = arguments[0])
373
+ receiver_type = typing.type_of(node: receiver)
374
+ arg_type = factory.deep_expand_alias(typing.type_of(node: arg))
375
+
376
+ if arg_type.is_a?(AST::Types::Name::Singleton)
377
+ truthy_type = arg_type
378
+ falsy_type = receiver_type
379
+ truthy_env, falsy_env = refine_node_type(
380
+ env: env,
381
+ node: receiver,
382
+ truthy_type: truthy_type,
383
+ falsy_type: falsy_type
384
+ )
385
+
386
+ truthy_result = Result.new(type: TRUE, env: truthy_env, unreachable: false)
387
+ truthy_result.unreachable! unless truthy_type
388
+
389
+ falsy_result = Result.new(type: FALSE, env: falsy_env, unreachable: false)
390
+ falsy_result.unreachable! unless falsy_type
391
+
392
+ [truthy_result, falsy_result]
393
+ end
394
+ end
395
+
370
396
  when AST::Types::Logic::Not
371
397
  if receiver
372
398
  truthy_result, falsy_result = evaluate_node(env: env, node: receiver)
@@ -453,7 +453,7 @@ module Steep
453
453
  has_error = false
454
454
 
455
455
  keywords.each do |keyword|
456
- rest_types << keyword_params.requireds[keyword] || keyword_params.optionals[keyword]
456
+ rest_types << (keyword_params.requireds[keyword] || keyword_params.optionals[keyword])
457
457
  has_error = true
458
458
  end
459
459
  keywords.clear
data/lib/steep/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Steep
2
- VERSION = "1.5.3"
2
+ VERSION = "1.6.0.pre.1"
3
3
  end
data/lib/steep.rb CHANGED
@@ -23,9 +23,6 @@ require "rbs"
23
23
 
24
24
  require "steep/path_helper"
25
25
 
26
- require "steep/shims/filter_map"
27
- require "steep/shims/symbol_start_with"
28
-
29
26
  require "steep/thread_waiter"
30
27
  require "steep/equatable"
31
28
  require "steep/method_name"
@@ -113,6 +110,7 @@ require "steep/services/stats_calculator"
113
110
  require "steep/services/file_loader"
114
111
  require "steep/services/goto_service"
115
112
 
113
+ require "steep/server/delay_queue"
116
114
  require "steep/server/lsp_formatter"
117
115
  require "steep/server/change_buffer"
118
116
  require "steep/server/base_worker"
@@ -78,6 +78,18 @@ module LanguageServer
78
78
  MARKDOWN: "markdown"
79
79
  end
80
80
 
81
+ class MessageType
82
+ type t = 1 | 2 | 3 | 4
83
+
84
+ ERROR: 1
85
+
86
+ WARNING: 2
87
+
88
+ INFO: 3
89
+
90
+ LOG: 4
91
+ end
92
+
81
93
  module DiagnosticSeverity
82
94
  type t = 1 | 2 | 3 | 4
83
95
 
@@ -52,6 +52,11 @@ module Steep
52
52
  def initialize: (?location: untyped?) -> void
53
53
  end
54
54
 
55
+ # A type for `Class#<` or `Class#<=` call results.
56
+ class ArgIsAncestor < Base
57
+ def initialize: (?location: untyped?) -> void
58
+ end
59
+
55
60
  # A type with truthy/falsy type environment.
56
61
  class Env < Base
57
62
  attr_reader truthy: TypeInference::TypeEnv
@@ -6,7 +6,7 @@ module Steep
6
6
  | Intersection | Record | Tuple | Union
7
7
  | Name::Alias | Name::Instance | Name::Interface | Name::Singleton
8
8
  | Proc | Var
9
- | Logic::Not | Logic::ReceiverIsNil | Logic::ReceiverIsNotNil | Logic::ReceiverIsArg | Logic::ArgIsReceiver | Logic::ArgEqualsReceiver | Logic::Env
9
+ | Logic::Not | Logic::ReceiverIsNil | Logic::ReceiverIsNotNil | Logic::ReceiverIsArg | Logic::ArgIsReceiver | Logic::ArgEqualsReceiver | Logic::ArgIsAncestor | Logic::Env
10
10
 
11
11
  # Variables and special types that is subject for substitution
12
12
  #
data/sig/steep/cli.rbs CHANGED
@@ -24,6 +24,8 @@ module Steep
24
24
 
25
25
  def handle_jobs_option: (Drivers::Utils::JobsOption jobs_option, OptionParser opts) -> void
26
26
 
27
+ def setup_jobs_for_ci: (Drivers::Utils::JobsOption) -> void
28
+
27
29
  def process_init: () -> Integer
28
30
 
29
31
  def process_check: () -> Integer