steep 1.8.0.pre.1 → 1.8.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c87015f545300c9c126b0121aa9534db083c157fbd791b7117006b6683bdc05d
4
- data.tar.gz: 6bb606ac1b4cc9cdd6364745c02f878714cdf2ca2d61079376a3ea50fbf4b9ba
3
+ metadata.gz: 298dd973658fa586efbf59424298b54eb540a3e8f5b5c423f10ede9ae83d0d65
4
+ data.tar.gz: f9a21241e44c10744d3305111b9afe499855931acda999b8671a2276ade4b2d9
5
5
  SHA512:
6
- metadata.gz: 4787c76c6049f2e1a2a9856d26dd0157419a2f4258a185559d0fe676500380089d75b30f916e353836f0e6af4eab16e2d977a9be5798bcfae1d13f8902d21491
7
- data.tar.gz: 462bb7747747fd5a34bf3205cd71d94f22beb4efd4407e5e59fbc31c049583b8350cdac262591319ad2ed09d802d94e3ff42d2f9c54ba0addff5547c7258f898
6
+ metadata.gz: e110b36e04ba367ba26ce2f2a74b7aa6be20bb25df742af696803be795f7b372a92948f923c4b30548ad4c78657b0dcb19702a602721ef80136eb4f9d4e9daa1
7
+ data.tar.gz: 2a4e44c76e29539b8692e31aa5cdd3f438715b978ef5d4e264d26191f634ff3c0ff58488d0334816ca8e6e6b1ff0ce3d0a35140c51e1dea78d7e3b56a31a3fdd
data/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 1.8.0 (2024-09-30)
4
+
5
+ ### Type checker core
6
+
7
+ * RBS validation ([#1239](https://github.com/soutaro/steep/pull/1239))
8
+ * Add special path for `Kernel#class` method ([#1229](https://github.com/soutaro/steep/pull/1229))
9
+
10
+ ## 1.8.0.pre.2 (2024-09-18)
11
+
12
+ ### Type checker core
13
+
14
+ * Support non symbol record keys ([#1227](https://github.com/soutaro/steep/pull/1227))
15
+
3
16
  ## 1.8.0.pre.1 (2024-09-17)
4
17
 
5
18
  ### Type checker core
@@ -65,6 +65,7 @@ module Steep
65
65
  Regexp = Type.new("::Regexp")
66
66
  NilClass = Type.new("::NilClass")
67
67
  Proc = Type.new("::Proc")
68
+ Kernel = Type.new("::Kernel")
68
69
 
69
70
  def self.nil_type
70
71
  AST::Types::Nil.instance
@@ -27,7 +27,7 @@ module Steep
27
27
  end
28
28
 
29
29
  def to_s
30
- strings = elements.keys.sort.map do |key|
30
+ strings = elements.keys.sort_by(&:to_s).map do |key|
31
31
  if optional?(key)
32
32
  "?#{key.inspect} => #{elements[key]}"
33
33
  else
@@ -0,0 +1,48 @@
1
+ module Steep
2
+ module Diagnostic
3
+ module ResultPrinter2
4
+ def result_line(result)
5
+ case result
6
+ when Subtyping::Result::Failure
7
+ case result.error
8
+ when Subtyping::Result::Failure::UnknownPairError
9
+ nil
10
+ when Subtyping::Result::Failure::UnsatisfiedConstraints
11
+ "Unsatisfied constraints: #{result.relation}"
12
+ when Subtyping::Result::Failure::MethodMissingError
13
+ "Method `#{result.error.name}` is missing"
14
+ when Subtyping::Result::Failure::BlockMismatchError
15
+ "Incomaptible block: #{result.relation}"
16
+ when Subtyping::Result::Failure::ParameterMismatchError
17
+ if result.relation.params?
18
+ "Incompatible arity: #{result.relation.super_type} and #{result.relation.sub_type}"
19
+ else
20
+ "Incompatible arity: #{result.relation}"
21
+ end
22
+ when Subtyping::Result::Failure::PolyMethodSubtyping
23
+ "Unsupported polymorphic method comparison: #{result.relation}"
24
+ when Subtyping::Result::Failure::SelfBindingMismatch
25
+ "Incompatible block self type: #{result.relation}"
26
+ end
27
+ else
28
+ result.relation.to_s
29
+ end
30
+ end
31
+
32
+ def detail_lines
33
+ lines = StringIO.new.tap do |io|
34
+ failure_path = result.failure_path || []
35
+ failure_path.reverse_each.filter_map do |result|
36
+ result_line(result)
37
+ end.each.with_index(1) do |message, index|
38
+ io.puts "#{" " * (index)}#{message}"
39
+ end
40
+ end.string.chomp
41
+
42
+ unless lines.empty?
43
+ lines
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -61,51 +61,6 @@ module Steep
61
61
  end
62
62
  end
63
63
 
64
- module ResultPrinter2
65
- def result_line(result)
66
- case result
67
- when Subtyping::Result::Failure
68
- case result.error
69
- when Subtyping::Result::Failure::UnknownPairError
70
- nil
71
- when Subtyping::Result::Failure::UnsatisfiedConstraints
72
- "Unsatisfied constraints: #{result.relation}"
73
- when Subtyping::Result::Failure::MethodMissingError
74
- "Method `#{result.error.name}` is missing"
75
- when Subtyping::Result::Failure::BlockMismatchError
76
- "Incomaptible block: #{result.relation}"
77
- when Subtyping::Result::Failure::ParameterMismatchError
78
- if result.relation.params?
79
- "Incompatible arity: #{result.relation.super_type} and #{result.relation.sub_type}"
80
- else
81
- "Incompatible arity: #{result.relation}"
82
- end
83
- when Subtyping::Result::Failure::PolyMethodSubtyping
84
- "Unsupported polymorphic method comparison: #{result.relation}"
85
- when Subtyping::Result::Failure::SelfBindingMismatch
86
- "Incompatible block self type: #{result.relation}"
87
- end
88
- else
89
- result.relation.to_s
90
- end
91
- end
92
-
93
- def detail_lines
94
- lines = StringIO.new.tap do |io|
95
- failure_path = result.failure_path || []
96
- failure_path.reverse_each.filter_map do |result|
97
- result_line(result)
98
- end.each.with_index(1) do |message, index|
99
- io.puts "#{" " * (index)}#{message}"
100
- end
101
- end.string.chomp
102
-
103
- unless lines.empty?
104
- lines
105
- end
106
- end
107
- end
108
-
109
64
  class IncompatibleAssignment < Base
110
65
  attr_reader :lhs_type
111
66
  attr_reader :rhs_type
@@ -105,12 +105,16 @@ module Steep
105
105
  attr_reader :type_name
106
106
  attr_reader :type_arg
107
107
  attr_reader :type_param
108
+ attr_reader :result
108
109
 
109
- def initialize(type_name:, type_arg:, type_param:, location:)
110
+ include ResultPrinter2
111
+
112
+ def initialize(type_name:, type_arg:, type_param:, result:, location:)
110
113
  super(location: location)
111
114
  @type_name = type_name
112
115
  @type_arg = type_arg
113
116
  @type_param = type_param
117
+ @result = result
114
118
  end
115
119
 
116
120
  def header_line
@@ -248,14 +252,20 @@ module Steep
248
252
  class ModuleSelfTypeError < Base
249
253
  attr_reader :name
250
254
  attr_reader :ancestor
251
- attr_reader :relation
255
+ attr_reader :result
256
+
257
+ include ResultPrinter2
252
258
 
253
- def initialize(name:, ancestor:, relation:, location:)
259
+ def initialize(name:, ancestor:, result:, location:)
254
260
  super(location: location)
255
261
 
256
262
  @name = name
257
263
  @ancestor = ancestor
258
- @relation = relation
264
+ @result = result
265
+ end
266
+
267
+ def relation
268
+ result.relation
259
269
  end
260
270
 
261
271
  def header_line
@@ -417,6 +427,40 @@ module Steep
417
427
  end
418
428
  end
419
429
 
430
+ class TypeParamDefaultReferenceError < Base
431
+ attr_reader :type_param
432
+
433
+ def initialize(type_param, location:)
434
+ super(location: location)
435
+ @type_param = type_param
436
+ end
437
+
438
+ def header_line
439
+ "The default type of `#{type_param.name}` cannot depend on optional type parameters"
440
+ end
441
+ end
442
+
443
+ class UnsatisfiableGenericsDefaultType < Base
444
+ attr_reader :param_name, :result
445
+
446
+ include ResultPrinter2
447
+
448
+ def initialize(param_name, result, location:)
449
+ super(location: location)
450
+ @param_name = param_name
451
+ @result = result
452
+ end
453
+
454
+ def relation
455
+ result.relation
456
+ end
457
+
458
+ def header_line
459
+ "The default type of `#{param_name}` doesn't satisfy upper bound constarint: #{relation}"
460
+ end
461
+ end
462
+
463
+
420
464
  def self.from_rbs_error(error, factory:)
421
465
  case error
422
466
  when RBS::ParsingError
@@ -515,6 +559,8 @@ module Steep
515
559
  Diagnostic::Signature::InconsistentClassModuleAliasError.new(decl: error.alias_entry.decl)
516
560
  when RBS::CyclicClassAliasDefinitionError
517
561
  Diagnostic::Signature::CyclicClassAliasDefinitionError.new(decl: error.alias_entry.decl)
562
+ when RBS::TypeParamDefaultReferenceError
563
+ Diagnostic::Signature::TypeParamDefaultReferenceError.new(error.type_param, location: error.location)
518
564
  else
519
565
  raise error
520
566
  end
@@ -281,6 +281,7 @@ module Steep
281
281
  method_name = method_name_for(type_def, name)
282
282
  method_type = factory.method_type(type_def.type)
283
283
  method_type = replace_primitive_method(method_name, type_def, method_type)
284
+ method_type = replace_kernel_class(method_name, type_def, method_type) { AST::Builtin::Class.instance_type }
284
285
  Shape::MethodOverload.new(method_type, [type_def])
285
286
  end
286
287
 
@@ -311,6 +312,9 @@ module Steep
311
312
  method_name = method_name_for(type_def, name)
312
313
  method_type = factory.method_type(type_def.type)
313
314
  method_type = replace_primitive_method(method_name, type_def, method_type)
315
+ if type_name.class?
316
+ method_type = replace_kernel_class(method_name, type_def, method_type) { AST::Types::Name::Singleton.new(name: type_name) }
317
+ end
314
318
  Shape::MethodOverload.new(method_type, [type_def])
315
319
  end
316
320
 
@@ -748,7 +752,7 @@ module Steep
748
752
  return_type: AST::Types::Logic::ReceiverIsNil.instance()
749
753
  )
750
754
  )
751
- end
755
+ end
752
756
  end
753
757
 
754
758
  when :!
@@ -801,6 +805,23 @@ module Steep
801
805
 
802
806
  method_type
803
807
  end
808
+
809
+ def replace_kernel_class(method_name, method_def, method_type)
810
+ defined_in = method_def.defined_in
811
+ member = method_def.member
812
+
813
+ if member.is_a?(RBS::AST::Members::MethodDefinition)
814
+ case method_name.method_name
815
+ when :class
816
+ case defined_in
817
+ when AST::Builtin::Kernel.module_name
818
+ return method_type.with(type: method_type.type.with(return_type: yield))
819
+ end
820
+ end
821
+ end
822
+
823
+ method_type
824
+ end
804
825
  end
805
826
  end
806
827
  end
@@ -104,6 +104,7 @@ module Steep
104
104
  unchecked: param.unchecked?,
105
105
  default_type: factory.type_opt(param.default_type)
106
106
  ),
107
+ result: result,
107
108
  location: location
108
109
  )
109
110
  end
@@ -252,6 +253,39 @@ module Steep
252
253
  end
253
254
  end
254
255
 
256
+ def validate_type_params(type_name, type_params)
257
+ if error_type_params = RBS::AST::TypeParam.validate(type_params)
258
+ error_type_params.each do |type_param|
259
+ default_type = type_param.default_type or raise
260
+ @errors << Diagnostic::Signature::TypeParamDefaultReferenceError.new(type_param, location: default_type.location)
261
+ end
262
+ end
263
+
264
+ upper_bounds = type_params.each.with_object({}) do |param, bounds| #$ Hash[Symbol, AST::Types::t?]
265
+ bounds[param.name] = factory.type_opt(param.upper_bound_type)
266
+ end
267
+
268
+ checker.push_variable_bounds(upper_bounds) do
269
+ type_params.each do |type_param|
270
+ param = checker.factory.type_param(type_param)
271
+
272
+ default_type = param.default_type or next
273
+ upper_bound = param.upper_bound or next
274
+
275
+ relation = Subtyping::Relation.new(sub_type: default_type, super_type: upper_bound)
276
+ result = checker.check(relation, self_type: nil, instance_type: nil, class_type: nil, constraints: Subtyping::Constraints.empty)
277
+
278
+ if result.failure?
279
+ @errors << Diagnostic::Signature::UnsatisfiableGenericsDefaultType.new(
280
+ type_param.name,
281
+ result,
282
+ location: (type_param.default_type || raise).location
283
+ )
284
+ end
285
+ end
286
+ end
287
+ end
288
+
255
289
  def validate_one_class_decl(name, entry)
256
290
  rescue_validation_errors(name) do
257
291
  Steep.logger.debug { "Validating class definition `#{name}`..." }
@@ -310,7 +344,7 @@ module Steep
310
344
  name: name,
311
345
  location: ancestor.source&.location || raise,
312
346
  ancestor: ancestor,
313
- relation: relation
347
+ result: _1
314
348
  )
315
349
  end
316
350
  end
@@ -405,7 +439,7 @@ module Steep
405
439
  name: name,
406
440
  location: ancestor.source&.location || raise,
407
441
  ancestor: ancestor,
408
- relation: relation
442
+ result: _1
409
443
  )
410
444
  end
411
445
  end
@@ -419,6 +453,8 @@ module Steep
419
453
  validate_definition_type(definition)
420
454
  end
421
455
  end
456
+
457
+ validate_type_params(name, entry.type_params)
422
458
  end
423
459
  end
424
460
  end
@@ -480,6 +516,8 @@ module Steep
480
516
  Steep.logger.tagged "#{name}" do
481
517
  definition = builder.build_interface(name)
482
518
 
519
+ validate_type_params(name, definition.type_params_decl)
520
+
483
521
  upper_bounds = definition.type_params_decl.each.with_object({}) do |param, bounds|
484
522
  bounds[param.name] = factory.type_opt(param.upper_bound_type)
485
523
  end
@@ -575,6 +613,8 @@ module Steep
575
613
  builder.validate_type_name(outer, entry.decl.location&.aref(:name))
576
614
  end
577
615
 
616
+ validate_type_params(name, entry.decl.type_params)
617
+
578
618
  upper_bounds = entry.decl.type_params.each.with_object({}) do |param, bounds|
579
619
  bounds[param.name] = factory.type_opt(param.upper_bound_type)
580
620
  end
@@ -2657,34 +2657,11 @@ module Steep
2657
2657
  def synthesize_sendish(node, hint:, tapp:)
2658
2658
  case node.type
2659
2659
  when :send
2660
- yield_self do
2661
- if self_class?(node)
2662
- module_type = expand_alias(module_context.module_type)
2663
- type = if module_type.is_a?(AST::Types::Name::Singleton)
2664
- AST::Types::Name::Singleton.new(name: module_type.name)
2665
- else
2666
- module_type
2667
- end
2668
-
2669
- add_typing(node, type: type)
2670
- else
2671
- type_send(node, send_node: node, block_params: nil, block_body: nil, tapp: tapp, hint: hint)
2672
- end
2673
- end
2660
+ type_send(node, send_node: node, block_params: nil, block_body: nil, tapp: tapp, hint: hint)
2674
2661
  when :csend
2675
2662
  yield_self do
2676
2663
  send_type, constr =
2677
- if self_class?(node)
2678
- module_type = expand_alias(module_context.module_type)
2679
- type = if module_type.is_a?(AST::Types::Name::Singleton)
2680
- AST::Types::Name::Singleton.new(name: module_type.name)
2681
- else
2682
- module_type
2683
- end
2684
- add_typing(node, type: type).to_ary
2685
- else
2686
- type_send(node, send_node: node, block_params: nil, block_body: nil, unwrap: true, tapp: tapp, hint: hint).to_ary
2687
- end
2664
+ type_send(node, send_node: node, block_params: nil, block_body: nil, unwrap: true, tapp: tapp, hint: hint).to_ary
2688
2665
 
2689
2666
  constr
2690
2667
  .update_type_env { context.type_env.join(constr.context.type_env, context.type_env) }
@@ -4687,10 +4664,6 @@ module Steep
4687
4664
  add_typing node, type: AST::Builtin.any_type
4688
4665
  end
4689
4666
 
4690
- def self_class?(node)
4691
- node.type == :send && node.children[0]&.type == :self && node.children[1] == :class
4692
- end
4693
-
4694
4667
  def namespace_module?(node)
4695
4668
  # @type var nodes: Array[Parser::AST::Node]
4696
4669
  nodes =
@@ -4962,11 +4935,11 @@ module Steep
4962
4935
  each_child_node(hash_node) do |child|
4963
4936
  if child.type == :pair
4964
4937
  case child.children[0].type
4965
- when :sym
4938
+ when :sym, :int, :str, :true, :false
4966
4939
  key_node = child.children[0] #: Parser::AST::Node
4967
4940
  value_node = child.children[1] #: Parser::AST::Node
4968
4941
 
4969
- key = key_node.children[0] #: String | Symbol | Integer
4942
+ key = key_node.children[0] #: AST::Types::Record::key
4970
4943
 
4971
4944
  _, constr = constr.synthesize(key_node, hint: AST::Types::Literal.new(value: key))
4972
4945
 
data/lib/steep/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Steep
2
- VERSION = "1.8.0.pre.1"
2
+ VERSION = "1.8.0"
3
3
  end
data/lib/steep.rb CHANGED
@@ -75,6 +75,7 @@ require "steep/subtyping/constraints"
75
75
  require "steep/subtyping/variable_variance"
76
76
 
77
77
  require "steep/diagnostic/helper"
78
+ require "steep/diagnostic/result_printer2"
78
79
  require "steep/diagnostic/ruby"
79
80
  require "steep/diagnostic/signature"
80
81
  require "steep/diagnostic/lsp_formatter"
@@ -0,0 +1,15 @@
1
+ module LocationHelper : _WithLocation
2
+ interface _WithLocation
3
+ def location_method: () -> String
4
+ end
5
+
6
+ def hello: () -> void
7
+ end
8
+
9
+ class StringGeneric[X < Integer, Y < Integer = String]
10
+ def location_method: () -> Integer
11
+
12
+ include LocationHelper
13
+ extend LocationHelper
14
+ end
15
+
data/steep.gemspec CHANGED
@@ -36,7 +36,7 @@ Gem::Specification.new do |spec|
36
36
  spec.add_runtime_dependency "rainbow", ">= 2.2.2", "< 4.0"
37
37
  spec.add_runtime_dependency "listen", "~> 3.0"
38
38
  spec.add_runtime_dependency "language_server-protocol", ">= 3.15", "< 4.0"
39
- spec.add_runtime_dependency "rbs", "~> 3.6.0.dev"
39
+ spec.add_runtime_dependency "rbs", "~> 3.6.0"
40
40
  spec.add_runtime_dependency "concurrent-ruby", ">= 1.1.10"
41
41
  spec.add_runtime_dependency "terminal-table", ">= 2", "< 4"
42
42
  spec.add_runtime_dependency "securerandom", ">= 0.1"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: steep
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.0.pre.1
4
+ version: 1.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Soutaro Matsumoto
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-09-17 00:00:00.000000000 Z
11
+ date: 2024-09-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parser
@@ -98,14 +98,14 @@ dependencies:
98
98
  requirements:
99
99
  - - "~>"
100
100
  - !ruby/object:Gem::Version
101
- version: 3.6.0.dev
101
+ version: 3.6.0
102
102
  type: :runtime
103
103
  prerelease: false
104
104
  version_requirements: !ruby/object:Gem::Requirement
105
105
  requirements:
106
106
  - - "~>"
107
107
  - !ruby/object:Gem::Version
108
- version: 3.6.0.dev
108
+ version: 3.6.0
109
109
  - !ruby/object:Gem::Dependency
110
110
  name: concurrent-ruby
111
111
  requirement: !ruby/object:Gem::Requirement
@@ -291,6 +291,7 @@ files:
291
291
  - lib/steep/diagnostic/deprecated/unknown_constant_assigned.rb
292
292
  - lib/steep/diagnostic/helper.rb
293
293
  - lib/steep/diagnostic/lsp_formatter.rb
294
+ - lib/steep/diagnostic/result_printer2.rb
294
295
  - lib/steep/diagnostic/ruby.rb
295
296
  - lib/steep/diagnostic/signature.rb
296
297
  - lib/steep/drivers/annotations.rb
@@ -384,6 +385,7 @@ files:
384
385
  - sample/lib/conference.rb
385
386
  - sample/lib/length.rb
386
387
  - sample/sig/conference.rbs
388
+ - sample/sig/generics.rbs
387
389
  - sample/sig/length.rbs
388
390
  - steep.gemspec
389
391
  homepage: https://github.com/soutaro/steep
@@ -408,7 +410,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
408
410
  - !ruby/object:Gem::Version
409
411
  version: '0'
410
412
  requirements: []
411
- rubygems_version: 3.5.17
413
+ rubygems_version: 3.5.11
412
414
  signing_key:
413
415
  specification_version: 4
414
416
  summary: Gradual Typing for Ruby