steep 1.5.2 → 1.6.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 (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 +41 -0
  5. data/Gemfile +2 -4
  6. data/Gemfile.lock +37 -19
  7. data/gemfile_steep/Gemfile.lock +4 -4
  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 +60 -18
  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
@@ -710,7 +710,7 @@ module Steep
710
710
  end
711
711
  end
712
712
 
713
- p = pair.constr.synthesize(last_node, hint: hint)
713
+ p = pair.constr.synthesize(last_node, hint: hint, condition: condition)
714
714
  last_pair = pair + p
715
715
  last_pair.constr.add_typing(node, type: last_pair.type, constr: last_pair.constr)
716
716
  else
@@ -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.2"
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