steep 1.8.0.pre.2 → 1.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9ee676b84b4cf51568f84ecc88f1ec50591f2ee0b45b435ce3eafd4416c07193
4
- data.tar.gz: 86b23102cdbe3dd578a25b14d5ab1d8240cdf201124ad9342fa24bfe8baedfca
3
+ metadata.gz: 298dd973658fa586efbf59424298b54eb540a3e8f5b5c423f10ede9ae83d0d65
4
+ data.tar.gz: f9a21241e44c10744d3305111b9afe499855931acda999b8671a2276ade4b2d9
5
5
  SHA512:
6
- metadata.gz: 8f20566852d2a4815e5fdfc4e2756cd11c530326e59488268d707781c615a2e5f2987aecc0a5e705f737b1099a78849a7f84e879a086c1a4f578d6259aa000c3
7
- data.tar.gz: cdd82bc25963caee0195a35a9c8255f3e34d3b6cf2ffae9a34c5fe0affd0b32cab6c04071adf73d8a86ef9538de14d2a8a6420939e0fa67de3725ff8aeab779e
6
+ metadata.gz: e110b36e04ba367ba26ce2f2a74b7aa6be20bb25df742af696803be795f7b372a92948f923c4b30548ad4c78657b0dcb19702a602721ef80136eb4f9d4e9daa1
7
+ data.tar.gz: 2a4e44c76e29539b8692e31aa5cdd3f438715b978ef5d4e264d26191f634ff3c0ff58488d0334816ca8e6e6b1ff0ce3d0a35140c51e1dea78d7e3b56a31a3fdd
data/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
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
+
3
10
  ## 1.8.0.pre.2 (2024-09-18)
4
11
 
5
12
  ### 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
@@ -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 =
data/lib/steep/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Steep
2
- VERSION = "1.8.0.pre.2"
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.pre"
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.2
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-18 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.pre
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.pre
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