steep 2.0.0 → 2.1.0

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.
@@ -189,7 +189,7 @@ module Steep
189
189
 
190
190
  relation.type!
191
191
 
192
- Steep.logger.tagged "#{relation.sub_type} <: #{relation.super_type}" do
192
+ Steep.logger.tagged(-> { "#{relation.sub_type} <: #{relation.super_type}" }) do
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]
@@ -201,7 +201,7 @@ module Steep
201
201
  else
202
202
  push_assumption(relation) do
203
203
  check_type0(relation).tap do |result|
204
- Steep.logger.debug "result=#{result.class}"
204
+ Steep.logger.debug { "result=#{result.class}" }
205
205
  cache[relation, @self_type, @instance_type, @class_type, bounds] = result
206
206
  end
207
207
  end
@@ -644,6 +644,9 @@ module Steep
644
644
 
645
645
  All(relation) do |result|
646
646
  sub_args.zip(sup_args, sup_params.each).each do |sub_arg, sup_arg, sup_param|
647
+ sup_arg or raise
648
+ sup_param or raise
649
+
647
650
  case sup_param.variance
648
651
  when :covariant
649
652
  result.add(Relation.new(sub_type: sub_arg, super_type: sup_arg)) do |rel|
@@ -854,7 +857,7 @@ module Steep
854
857
  end
855
858
 
856
859
  def check_method_type(name, relation)
857
- Steep.logger.tagged "#{name} : #{relation.sub_type} <: #{relation.super_type}" do
860
+ Steep.logger.tagged(-> { "#{name} : #{relation.sub_type} <: #{relation.super_type}" }) do
858
861
  relation.method!
859
862
 
860
863
  sub_type, super_type = relation
@@ -33,7 +33,10 @@ module Steep
33
33
  end
34
34
 
35
35
  def formatted_tags
36
- current_tags.map { |tag| "[#{tag}]" }.join(" ")
36
+ current_tags.map do |tag|
37
+ tag = tag.call if tag.is_a?(Proc)
38
+ "[#{tag}]"
39
+ end.join(" ")
37
40
  end
38
41
  end
39
42
  end
@@ -653,7 +653,6 @@ module Steep
653
653
  instance_definition: instance_definition
654
654
  )
655
655
 
656
- singleton_definition = checker.factory.definition_builder.build_singleton(module_context.class_name)
657
656
  type_env =
658
657
  TypeInference::TypeEnvBuilder.new(
659
658
  TypeInference::TypeEnvBuilder::Command::ImportGlobalDeclarations.new(checker.factory),
@@ -730,7 +729,7 @@ module Steep
730
729
  end
731
730
 
732
731
  def synthesize(node, hint: nil, condition: false)
733
- Steep.logger.tagged "synthesize:(#{node.location&.yield_self {|loc| loc.expression.to_s.split(/:/, 2).last } || "-"})" do
732
+ Steep.logger.tagged(-> { "synthesize:(#{node.location&.yield_self {|loc| loc.expression.to_s.split(/:/, 2).last } || "-"})" }) do
734
733
  Steep.logger.debug node.type
735
734
  case node.type
736
735
  when :begin, :kwbegin
@@ -781,7 +780,7 @@ module Steep
781
780
  end
782
781
 
783
782
  if rhs
784
- rhs_type, rhs_constr, rhs_context = synthesize(rhs, hint: hint).to_ary
783
+ rhs_type, rhs_constr, _ = synthesize(rhs, hint: hint).to_ary
785
784
 
786
785
  constr = rhs_constr.update_type_env do |type_env|
787
786
  var_type = rhs_type
@@ -1761,6 +1760,11 @@ module Steep
1761
1760
  else
1762
1761
  if hint
1763
1762
  tuples = select_flatten_types(hint) {|type| type.is_a?(AST::Types::Tuple) } #: Array[AST::Types::Tuple]
1763
+ if tuples.empty?
1764
+ if converted = try_convert(hint, :to_ary)
1765
+ tuples = select_flatten_types(converted) {|type| type.is_a?(AST::Types::Tuple) } #: Array[AST::Types::Tuple]
1766
+ end
1767
+ end
1764
1768
  unless tuples.empty?
1765
1769
  fallback_pair = nil #: Pair?
1766
1770
  tuples.each do |tuple|
@@ -1913,7 +1917,7 @@ module Steep
1913
1917
  yield_self do
1914
1918
  cond, true_clause, false_clause = node.children
1915
1919
 
1916
- cond_type, constr = synthesize(cond, condition: true).to_ary
1920
+ _, constr = synthesize(cond, condition: true).to_ary
1917
1921
  interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: constr.typing, config: builder_config)
1918
1922
  truthy, falsy = interpreter.eval(env: constr.context.type_env, node: cond)
1919
1923
 
@@ -2045,7 +2049,7 @@ module Steep
2045
2049
  branch_reachable = false
2046
2050
 
2047
2051
  tests.each do |test|
2048
- test_type, condition_constr = condition_constr.synthesize(test, condition: true)
2052
+ _, condition_constr = condition_constr.synthesize(test, condition: true)
2049
2053
  truthy, falsy = interpreter.eval(env: condition_constr.context.type_env, node: test)
2050
2054
  truthy_env = truthy.env
2051
2055
  falsy_env = falsy.env
@@ -2295,7 +2299,7 @@ module Steep
2295
2299
  when :while, :until
2296
2300
  yield_self do
2297
2301
  cond, body = node.children
2298
- cond_type, constr = synthesize(cond, condition: true).to_ary
2302
+ _, constr = synthesize(cond, condition: true).to_ary
2299
2303
 
2300
2304
  interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: typing, config: builder_config)
2301
2305
  truthy, falsy = interpreter.eval(env: constr.context.type_env, node: cond)
@@ -2347,7 +2351,7 @@ module Steep
2347
2351
  .for_branch(body, break_context: TypeInference::Context::BreakContext.new(break_type: hint || AST::Builtin.nil_type, next_type: nil))
2348
2352
 
2349
2353
  typing.cursor_context.set_node_context(body, for_loop.context)
2350
- _, body_constr, body_context = for_loop.synthesize(body)
2354
+ _, _, body_context = for_loop.synthesize(body)
2351
2355
 
2352
2356
  constr = cond_constr.update_type_env {|env| env.join(env, body_context.type_env) }
2353
2357
 
@@ -2696,7 +2700,7 @@ module Steep
2696
2700
  constr.add_typing(node, type: type)
2697
2701
  end
2698
2702
 
2699
- when :block, :numblock, :send, :csend
2703
+ when :block, :numblock, :itblock, :send, :csend
2700
2704
  synthesize_sendish(node, hint: hint, tapp: nil)
2701
2705
 
2702
2706
  when :forwarded_args, :forward_arg
@@ -2772,6 +2776,20 @@ module Steep
2772
2776
 
2773
2777
  params = Parser::AST::Node.new(:args, arg_nodes)
2774
2778
 
2779
+ if send_node.type == :lambda
2780
+ # @type var node: Parser::AST::Node & Parser::AST::_BlockNode
2781
+ type_lambda(node, params_node: params, body_node: body, type_hint: hint)
2782
+ else
2783
+ type_send(node, send_node: send_node, block_params: params, block_body: body, unwrap: send_node.type == :csend, tapp: tapp, hint: hint)
2784
+ end
2785
+ end
2786
+ when :itblock
2787
+ yield_self do
2788
+ send_node, _name, body = node.children
2789
+
2790
+ arg_nodes = [Parser::AST::Node.new(:procarg0, [:it])]
2791
+ params = Parser::AST::Node.new(:args, arg_nodes)
2792
+
2775
2793
  if send_node.type == :lambda
2776
2794
  # @type var node: Parser::AST::Node & Parser::AST::_BlockNode
2777
2795
  type_lambda(node, params_node: params, body_node: body, type_hint: hint)
@@ -2872,10 +2890,8 @@ module Steep
2872
2890
  if node.type == :splat
2873
2891
  asgn_node = node.children[0]
2874
2892
  next unless asgn_node
2875
- var_type = asgn_node.type
2876
2893
  else
2877
2894
  asgn_node = node
2878
- var_type = type
2879
2895
  end
2880
2896
 
2881
2897
  case asgn_node.type
@@ -3150,11 +3166,14 @@ module Steep
3150
3166
  block =
3151
3167
  if block_param = params.block_param
3152
3168
  if block_param_type = block_param.type
3153
- case block_param_type
3169
+ # Expanding aliases because the cases below test the structure of the type
3170
+ expanded_type = deep_expand_alias(block_param_type) || block_param_type
3171
+
3172
+ case expanded_type
3154
3173
  when AST::Types::Proc
3155
- Interface::Block.new(type: block_param_type.type, optional: false, self_type: block_param_type.self_type)
3174
+ Interface::Block.new(type: expanded_type.type, optional: false, self_type: expanded_type.self_type)
3156
3175
  else
3157
- if proc_type = optional_proc?(block_param_type)
3176
+ if proc_type = optional_proc?(expanded_type)
3158
3177
  Interface::Block.new(type: proc_type.type, optional: true, self_type: proc_type.self_type)
3159
3178
  else
3160
3179
  block_constr.typing.add_error(
@@ -3346,7 +3365,7 @@ module Steep
3346
3365
  end
3347
3366
  end
3348
3367
 
3349
- if node.type == :csend || ((node.type == :block || node.type == :numblock) && node.children[0].type == :csend)
3368
+ if node.type == :csend || ((node.type == :block || node.type == :numblock || node.type == :itblock) && node.children[0].type == :csend)
3350
3369
  optional_type = AST::Types::Union.build(types: [call.return_type, AST::Builtin.nil_type])
3351
3370
  call = call.with_return_type(optional_type)
3352
3371
  end
@@ -3509,7 +3528,7 @@ module Steep
3509
3528
 
3510
3529
  when AST::Types::Any
3511
3530
  case node.type
3512
- when :block, :numblock
3531
+ when :block, :numblock, :itblock
3513
3532
  # @type var node: Parser::AST::Node & Parser::AST::_BlockNode
3514
3533
  block_annotations = source.annotations(block: node, factory: checker.factory, context: nesting)
3515
3534
  block_params or raise
@@ -4344,7 +4363,9 @@ module Steep
4344
4363
  when arg.compatible?
4345
4364
  if arg.node
4346
4365
  # Block pass (&block) is given
4347
- node_type, constr = constr.synthesize(arg.node, hint: arg.node_type)
4366
+ # Passing `proc_type` instead of `node_type` because a block-pass argument is a proc, not `nil`.
4367
+ # `nil` is still allowed by the `node_type` check below.
4368
+ node_type, constr = constr.synthesize(arg.node, hint: arg.proc_type)
4348
4369
 
4349
4370
  nil_given =
4350
4371
  constr.check_relation(sub_type: node_type, super_type: AST::Builtin.nil_type).success? &&
@@ -20,14 +20,14 @@ module Steep
20
20
 
21
21
  latest_constr, unreachable_pattern = latest_result
22
22
 
23
- type, constr = yield(test_node, latest_constr, unreachable_pattern)
23
+ yield(test_node, latest_constr, unreachable_pattern)
24
24
  truthy_result, falsy_result = logic.eval(env: latest_constr.context.type_env, node: test_node)
25
25
 
26
26
  pattern_results << [pat, truthy_result, falsy_result]
27
27
  end
28
28
 
29
29
  def latest_result
30
- if (_, truthy, falsy = pattern_results.last)
30
+ if (_, _, falsy = pattern_results.last)
31
31
  [
32
32
  initial_constr.update_type_env { falsy.env },
33
33
  falsy.unreachable
@@ -564,9 +564,12 @@ module Steep
564
564
  false_types << type
565
565
  end
566
566
  else
567
- # For === (for_receiver: false), non-literal types can match the literal in truthy branch
568
- # For == (for_receiver: true), non-literal types only go to falsy branch
569
- true_types << AST::Types::Literal.new(value: value_node.children[0]) unless for_receiver
567
+ # For `==`, narrow only when the literal can be a value of `type`.
568
+ # e.g. `Symbol == :fatal` can be true, but `SomeClass == :fatal` cannot.
569
+ literal_type = AST::Types::Literal.new(value: value_node.children[0])
570
+ if !for_receiver || subtyping?(sub_type: literal_type, super_type: type)
571
+ true_types << literal_type
572
+ end
570
573
  false_types << type
571
574
  end
572
575
  end
@@ -473,16 +473,20 @@ module Steep
473
473
  end
474
474
  end
475
475
 
476
- def node_type
476
+ def proc_type
477
477
  raise unless block
478
478
 
479
- type = AST::Types::Proc.new(type: block.type, block: nil, self_type: block.self_type)
479
+ AST::Types::Proc.new(type: block.type, block: nil, self_type: block.self_type)
480
+ end
481
+
482
+ def node_type
483
+ raise unless block
480
484
 
481
485
  if block.optional?
482
- type = AST::Types::Union.build(types: [type, AST::Builtin.nil_type])
486
+ AST::Types::Union.build(types: [proc_type, AST::Builtin.nil_type])
487
+ else
488
+ proc_type
483
489
  end
484
-
485
- type
486
490
  end
487
491
  end
488
492
 
data/lib/steep/typing.rb CHANGED
@@ -106,7 +106,7 @@ module Steep
106
106
  set(body_begin_pos..body_end_pos, context)
107
107
  end
108
108
 
109
- when :block, :numblock
109
+ when :block, :numblock, :itblock
110
110
  range = block_range(node)
111
111
  set(range, context)
112
112
 
@@ -132,7 +132,7 @@ module Steep
132
132
  node.loc.begin.end_pos # steep:ignore NoMethod
133
133
  end
134
134
  end_pos = node.loc.end.begin_pos # steep:ignore NoMethod
135
- when :numblock
135
+ when :numblock, :itblock
136
136
  send_node, _ = node.children
137
137
  begin_pos = node.loc.begin.end_pos # steep:ignore NoMethod
138
138
  end_pos = node.loc.end.begin_pos # steep:ignore NoMethod
@@ -245,7 +245,7 @@ module Steep
245
245
  node.loc.begin.end_pos # steep:ignore NoMethod
246
246
  end
247
247
  end_pos = node.loc.end.begin_pos # steep:ignore NoMethod
248
- when :numblock
248
+ when :numblock, :itblock
249
249
  send_node, _ = node.children
250
250
  begin_pos = node.loc.begin.end_pos # steep:ignore NoMethod
251
251
  end_pos = node.loc.end.begin_pos # steep:ignore NoMethod
data/lib/steep/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Steep
2
- VERSION = "2.0.0"
2
+ VERSION = "2.1.0"
3
3
  end
data/lib/steep.rb CHANGED
@@ -133,6 +133,7 @@ require "steep/server/target_group_files"
133
133
  require "steep/server/type_check_controller"
134
134
  require "steep/server/inline_source_change_detector"
135
135
  require "steep/server/master"
136
+ require "steep/server/command_socket"
136
137
  require "steep/daemon"
137
138
 
138
139
  require "steep/project"
data/steep.gemspec CHANGED
@@ -29,20 +29,14 @@ Gem::Specification.new do |spec|
29
29
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
30
30
  spec.require_paths = ["lib"]
31
31
 
32
- if false
33
- # This is to let dependabot use 3.3, instead of 3.1.x.
34
- # They use `required_ruby_version=` method to detect the Ruby version they use.
35
- spec.required_ruby_version = ">= 3.3.0"
36
- end
37
-
38
- spec.required_ruby_version = '>= 3.2.0'
32
+ spec.required_ruby_version = '>= 3.3.0'
39
33
 
40
34
  spec.add_runtime_dependency "parser", ">= 3.2"
41
35
  spec.add_runtime_dependency "prism", ">= 0.25.0"
42
36
  spec.add_runtime_dependency "rainbow", ">= 2.2.2", "< 4.0"
43
37
  spec.add_runtime_dependency "listen", "~> 3.0"
44
38
  spec.add_runtime_dependency "language_server-protocol", ">= 3.17.0.4", "< 4.0"
45
- spec.add_runtime_dependency "rbs", "~> 4.0"
39
+ spec.add_runtime_dependency "rbs", "~> 4.2"
46
40
  spec.add_runtime_dependency "concurrent-ruby", ">= 1.1.10"
47
41
  spec.add_runtime_dependency "terminal-table", ">= 2", "< 5"
48
42
  spec.add_runtime_dependency "securerandom", ">= 0.1"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: steep
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Soutaro Matsumoto
@@ -97,14 +97,14 @@ dependencies:
97
97
  requirements:
98
98
  - - "~>"
99
99
  - !ruby/object:Gem::Version
100
- version: '4.0'
100
+ version: '4.2'
101
101
  type: :runtime
102
102
  prerelease: false
103
103
  version_requirements: !ruby/object:Gem::Requirement
104
104
  requirements:
105
105
  - - "~>"
106
106
  - !ruby/object:Gem::Version
107
- version: '4.0'
107
+ version: '4.2'
108
108
  - !ruby/object:Gem::Dependency
109
109
  name: concurrent-ruby
110
110
  requirement: !ruby/object:Gem::Requirement
@@ -267,6 +267,7 @@ files:
267
267
  - bin/steep-check.rb
268
268
  - bin/steep-prof
269
269
  - doc/narrowing.md
270
+ - doc/release.md
270
271
  - doc/shape.md
271
272
  - exe/steep
272
273
  - guides/README.md
@@ -361,6 +362,7 @@ files:
361
362
  - lib/steep/range_extension.rb
362
363
  - lib/steep/server/base_worker.rb
363
364
  - lib/steep/server/change_buffer.rb
365
+ - lib/steep/server/command_socket.rb
364
366
  - lib/steep/server/custom_methods.rb
365
367
  - lib/steep/server/delay_queue.rb
366
368
  - lib/steep/server/inline_source_change_detector.rb
@@ -441,14 +443,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
441
443
  requirements:
442
444
  - - ">="
443
445
  - !ruby/object:Gem::Version
444
- version: 3.2.0
446
+ version: 3.3.0
445
447
  required_rubygems_version: !ruby/object:Gem::Requirement
446
448
  requirements:
447
449
  - - ">="
448
450
  - !ruby/object:Gem::Version
449
451
  version: '0'
450
452
  requirements: []
451
- rubygems_version: 4.0.6
453
+ rubygems_version: 4.0.19
452
454
  specification_version: 4
453
455
  summary: Gradual Typing for Ruby
454
456
  test_files: []