steep 0.34.0 → 0.39.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +31 -0
  3. data/lib/steep.rb +6 -0
  4. data/lib/steep/ast/types/bot.rb +1 -1
  5. data/lib/steep/ast/types/factory.rb +122 -53
  6. data/lib/steep/ast/types/logic.rb +33 -1
  7. data/lib/steep/ast/types/proc.rb +32 -20
  8. data/lib/steep/ast/types/top.rb +1 -1
  9. data/lib/steep/cli.rb +2 -2
  10. data/lib/steep/drivers/print_project.rb +11 -0
  11. data/lib/steep/drivers/vendor.rb +1 -20
  12. data/lib/steep/errors.rb +67 -38
  13. data/lib/steep/index/rbs_index.rb +334 -0
  14. data/lib/steep/index/signature_symbol_provider.rb +154 -0
  15. data/lib/steep/index/source_index.rb +100 -0
  16. data/lib/steep/interface/block.rb +79 -0
  17. data/lib/steep/interface/function.rb +770 -0
  18. data/lib/steep/interface/method_type.rb +32 -812
  19. data/lib/steep/project/dsl.rb +13 -17
  20. data/lib/steep/project/options.rb +4 -4
  21. data/lib/steep/project/target.rb +21 -12
  22. data/lib/steep/server/master.rb +5 -1
  23. data/lib/steep/server/signature_worker.rb +63 -6
  24. data/lib/steep/signature/errors.rb +51 -5
  25. data/lib/steep/signature/validator.rb +28 -4
  26. data/lib/steep/subtyping/check.rb +72 -34
  27. data/lib/steep/subtyping/variable_occurrence.rb +2 -2
  28. data/lib/steep/subtyping/variable_variance.rb +2 -2
  29. data/lib/steep/type_construction.rb +308 -152
  30. data/lib/steep/type_inference/block_params.rb +1 -1
  31. data/lib/steep/type_inference/constant_env.rb +5 -1
  32. data/lib/steep/type_inference/logic_type_interpreter.rb +102 -26
  33. data/lib/steep/typing.rb +8 -2
  34. data/lib/steep/version.rb +1 -1
  35. data/smoke/tsort/Steepfile +6 -0
  36. data/smoke/tsort/a.rb +15 -0
  37. data/smoke/type_case/a.rb +1 -1
  38. data/steep.gemspec +1 -1
  39. metadata +12 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0ec77465913e4b2146e068c58f63b7ae8b5c51fd2391f6eb2776dba8372a81c2
4
- data.tar.gz: 7528dbaf4873d9eb77728521837ecb0fe43a2010036572be2c3dc017c5b903cc
3
+ metadata.gz: 33c89b6005654ebdc947af336b1c7fa47e02c45c480d27b9f4ef0ab6d3403dd1
4
+ data.tar.gz: be7b7812e1ba321b91680884fccc55fd57dd5836c89bf7817624b72706490d6e
5
5
  SHA512:
6
- metadata.gz: b0426373f8fb9e48ccec48d0676d70d5a674a389a83624df78dc3deacaba23840b02cc94becba92304de35f98c8d8bb3af12ef185161e4e6a6c37600cb61a82d
7
- data.tar.gz: 5f3a32240541f116b6299c354fada0c8de398b6139b9d5e275e7b05490ccc401aa1b4f70978af5561e2ce9c6c7bb2587c1c8e43801276c0875000496ed332a5b
6
+ metadata.gz: 36945eb5fe4a04061c87bc76488c65ef2b009fcdb8279fd542a1249a10a223cd9571371f333e4ec29870a66dd120c4d9e65d572a9d3c90d56dba5c2c1dd95761
7
+ data.tar.gz: d9c2e56878f06d71edeb9a10b275c19afd7ba42b1af16ef01ef890ca3791ad4f92f903f7679fcf77b310638b0d0f5fced596e094ec225ff2f567e0f063bfc527
@@ -2,6 +2,37 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 0.39.0 (2020-12-25)
6
+
7
+ * Update RBS to 1.0.0 ([#282](https://github.com/soutaro/steep/pull/282))
8
+ * Better `&&` and `||` typing ([#276](https://github.com/soutaro/steep/pull/276))
9
+ * Type case based on literals ([#277](https://github.com/soutaro/steep/pull/277))
10
+ * Type case improvements ([#279](https://github.com/soutaro/steep/pull/279), [#283](https://github.com/soutaro/steep/pull/283))
11
+ * Improvements on untyped classes/modules, unsupported syntax error handling, and argument types in untyped methods ([#280](https://github.com/soutaro/steep/pull/280))
12
+ * Fix `bot` and `top` type format ([#278](https://github.com/soutaro/steep/pull/278))
13
+ * Colorfull error messages ([#273](https://github.com/soutaro/steep/pull/273))
14
+
15
+ ## 0.38.0 (2020-12-10)
16
+
17
+ * Improve `break`/`next` typing ([#271](https://github.com/soutaro/steep/pull/271))
18
+ * Add LSP `workspace/symbol` feature ([#267](https://github.com/soutaro/steep/pull/267))
19
+
20
+ ## 0.37.0 (2020-12-06)
21
+
22
+ * Update to RBS 0.20.0 with _singleton attribute_ syntax and _proc types with blocks_. ([#264](https://github.com/soutaro/steep/pull/264))
23
+
24
+ ## 0.36.0 (2020-11-16)
25
+
26
+ * Flow-sensitive typing improvements with `||` and `&&` ([#260](https://github.com/soutaro/steep/pull/260))
27
+ * Type-case improvement ([#259](https://github.com/soutaro/steep/pull/259))
28
+ * Subtyping between `bool` and logic types ([#258](https://github.com/soutaro/steep/pull/258))
29
+
30
+ ## 0.35.0 (2020-11-14)
31
+
32
+ * Support third party RBS repository ([#231](https://github.com/soutaro/steep/pull/231), [#254](https://github.com/soutaro/steep/pull/254), [#255](https://github.com/soutaro/steep/pull/255))
33
+ * Boolean type semantics update ([#252](https://github.com/soutaro/steep/pull/252))
34
+ * More flexible record typing ([#256](https://github.com/soutaro/steep/pull/256))
35
+
5
36
  ## 0.34.0 (2020-10-27)
6
37
 
7
38
  * Add `steep stats` command to show method call typing stats ([#246](https://github.com/soutaro/steep/pull/246))
@@ -42,6 +42,8 @@ require "steep/ast/annotation/collection"
42
42
  require "steep/ast/builtin"
43
43
  require "steep/ast/types/factory"
44
44
 
45
+ require "steep/interface/function"
46
+ require "steep/interface/block"
45
47
  require "steep/interface/method_type"
46
48
  require "steep/interface/substitution"
47
49
  require "steep/interface/interface"
@@ -74,6 +76,10 @@ require "steep/type_inference/logic_type_interpreter"
74
76
  require "steep/type_inference/method_call"
75
77
  require "steep/ast/types"
76
78
 
79
+ require "steep/index/rbs_index"
80
+ require "steep/index/signature_symbol_provider"
81
+ require "steep/index/source_index"
82
+
77
83
  require "steep/server/utils"
78
84
  require "steep/server/base_worker"
79
85
  require "steep/server/code_worker"
@@ -23,7 +23,7 @@ module Steep
23
23
  end
24
24
 
25
25
  def to_s
26
- ""
26
+ "bot"
27
27
  end
28
28
 
29
29
  include Helper::NoFreeVariables
@@ -75,9 +75,23 @@ module Steep
75
75
  end
76
76
  Record.new(elements: elements, location: nil)
77
77
  when RBS::Types::Proc
78
- params = params(type.type)
79
- return_type = type(type.type.return_type)
80
- Proc.new(params: params, return_type: return_type, location: nil)
78
+ func = Interface::Function.new(
79
+ params: params(type.type),
80
+ return_type: type(type.type.return_type),
81
+ location: type.location
82
+ )
83
+ block = if type.block
84
+ Interface::Block.new(
85
+ type: Interface::Function.new(
86
+ params: params(type.block.type),
87
+ return_type: type(type.block.type.return_type),
88
+ location: type.location
89
+ ),
90
+ optional: !type.block.required
91
+ )
92
+ end
93
+
94
+ Proc.new(type: func, block: block)
81
95
  else
82
96
  raise "Unexpected type given: #{type}"
83
97
  end
@@ -145,8 +159,15 @@ module Steep
145
159
  end
146
160
  RBS::Types::Record.new(fields: fields, location: nil)
147
161
  when Proc
162
+ block = if type.block
163
+ RBS::Types::Block.new(
164
+ type: function_1(type.block.type),
165
+ required: !type.block.optional?
166
+ )
167
+ end
148
168
  RBS::Types::Proc.new(
149
- type: function_1(type.params, type.return_type),
169
+ type: function_1(type.type),
170
+ block: block,
150
171
  location: nil
151
172
  )
152
173
  when Logic::Base
@@ -156,7 +177,10 @@ module Steep
156
177
  end
157
178
  end
158
179
 
159
- def function_1(params, return_type)
180
+ def function_1(func)
181
+ params = func.params
182
+ return_type = func.return_type
183
+
160
184
  RBS::Types::Function.new(
161
185
  required_positionals: params.required.map {|type| RBS::Types::Function::Param.new(name: nil, type: type_1(type)) },
162
186
  optional_positionals: params.optional.map {|type| RBS::Types::Function::Param.new(name: nil, type: type_1(type)) },
@@ -170,7 +194,7 @@ module Steep
170
194
  end
171
195
 
172
196
  def params(type)
173
- Interface::Params.new(
197
+ Interface::Function::Params.new(
174
198
  required: type.required_positionals.map {|param| type(param.type) },
175
199
  optional: type.optional_positionals.map {|param| type(param.type) },
176
200
  rest: type.rest_positionals&.yield_self {|param| type(param.type) },
@@ -202,13 +226,19 @@ module Steep
202
226
 
203
227
  type = Interface::MethodType.new(
204
228
  type_params: type_params,
205
- return_type: type(method_type.type.return_type).subst(subst),
206
- params: params(method_type.type).subst(subst),
229
+ type: Interface::Function.new(
230
+ params: params(method_type.type).subst(subst),
231
+ return_type: type(method_type.type.return_type).subst(subst),
232
+ location: method_type.location
233
+ ),
207
234
  block: method_type.block&.yield_self do |block|
208
235
  Interface::Block.new(
209
236
  optional: !block.required,
210
- type: Proc.new(params: params(block.type).subst(subst),
211
- return_type: type(block.type.return_type).subst(subst), location: nil)
237
+ type: Interface::Function.new(
238
+ params: params(block.type).subst(subst),
239
+ return_type: type(block.type.return_type).subst(subst),
240
+ location: nil
241
+ )
212
242
  )
213
243
  end,
214
244
  method_decls: method_decls
@@ -242,12 +272,12 @@ module Steep
242
272
 
243
273
  type = RBS::MethodType.new(
244
274
  type_params: type_params,
245
- type: function_1(method_type.params.subst(subst), method_type.return_type.subst(subst)),
275
+ type: function_1(method_type.type.subst(subst)),
246
276
  block: method_type.block&.yield_self do |block|
247
277
  block_type = block.type.subst(subst)
248
278
 
249
- RBS::MethodType::Block.new(
250
- type: function_1(block_type.params, block_type.return_type),
279
+ RBS::Types::Block.new(
280
+ type: function_1(block_type),
251
281
  required: !block.optional
252
282
  )
253
283
  end,
@@ -338,6 +368,8 @@ module Steep
338
368
  ]
339
369
  when AST::Types::Name::Alias
340
370
  unwrap_optional(expand_alias(type))
371
+ when AST::Types::Boolean
372
+ [AST::Builtin.true_type, AST::Builtin.false_type]
341
373
  else
342
374
  [type, nil]
343
375
  end
@@ -354,7 +386,9 @@ module Steep
354
386
  when :is_a?, :kind_of?, :instance_of?
355
387
  if defined_in == RBS::BuiltinNames::Object.name && member.instance?
356
388
  return method_type.with(
357
- return_type: AST::Types::Logic::ReceiverIsArg.new(location: method_type.return_type.location)
389
+ type: method_type.type.with(
390
+ return_type: AST::Types::Logic::ReceiverIsArg.new(location: method_type.type.return_type.location)
391
+ )
358
392
  )
359
393
  end
360
394
 
@@ -363,7 +397,9 @@ module Steep
363
397
  when RBS::BuiltinNames::Object.name,
364
398
  NilClassName
365
399
  return method_type.with(
366
- return_type: AST::Types::Logic::ReceiverIsNil.new(location: method_type.return_type.location)
400
+ type: method_type.type.with(
401
+ return_type: AST::Types::Logic::ReceiverIsNil.new(location: method_type.type.return_type.location)
402
+ )
367
403
  )
368
404
  end
369
405
 
@@ -373,7 +409,9 @@ module Steep
373
409
  RBS::BuiltinNames::TrueClass.name,
374
410
  RBS::BuiltinNames::FalseClass.name
375
411
  return method_type.with(
376
- return_type: AST::Types::Logic::Not.new(location: method_type.return_type.location)
412
+ type: method_type.type.with(
413
+ return_type: AST::Types::Logic::Not.new(location: method_type.type.return_type.location)
414
+ )
377
415
  )
378
416
  end
379
417
 
@@ -381,7 +419,17 @@ module Steep
381
419
  case defined_in
382
420
  when RBS::BuiltinNames::Module.name
383
421
  return method_type.with(
384
- return_type: AST::Types::Logic::ArgIsReceiver.new(location: method_type.return_type.location)
422
+ type: method_type.type.with(
423
+ return_type: AST::Types::Logic::ArgIsReceiver.new(location: method_type.type.return_type.location)
424
+ )
425
+ )
426
+ when RBS::BuiltinNames::Object.name, RBS::BuiltinNames::String.name, RBS::BuiltinNames::Integer.name, RBS::BuiltinNames::Symbol.name,
427
+ RBS::BuiltinNames::TrueClass.name, RBS::BuiltinNames::FalseClass.name, TypeName("::NilClass")
428
+ # Value based type-case works on literal types which is available for String, Integer, Symbol, TrueClass, FalseClass, and NilClass
429
+ return method_type.with(
430
+ type: method_type.type.with(
431
+ return_type: AST::Types::Logic::ArgEqualsReceiver.new(location: method_type.type.return_type.location)
432
+ )
385
433
  )
386
434
  end
387
435
  end
@@ -572,14 +620,17 @@ module Steep
572
620
  method_types: type.types.map.with_index {|elem_type, index|
573
621
  Interface::MethodType.new(
574
622
  type_params: [],
575
- params: Interface::Params.new(required: [AST::Types::Literal.new(value: index)],
576
- optional: [],
577
- rest: nil,
578
- required_keywords: {},
579
- optional_keywords: {},
580
- rest_keywords: nil),
623
+ type: Interface::Function.new(
624
+ params: Interface::Function::Params.new(required: [AST::Types::Literal.new(value: index)],
625
+ optional: [],
626
+ rest: nil,
627
+ required_keywords: {},
628
+ optional_keywords: {},
629
+ rest_keywords: nil),
630
+ return_type: elem_type,
631
+ location: nil
632
+ ),
581
633
  block: nil,
582
- return_type: elem_type,
583
634
  method_decls: Set[]
584
635
  )
585
636
  } + aref.method_types
@@ -591,14 +642,17 @@ module Steep
591
642
  method_types: type.types.map.with_index {|elem_type, index|
592
643
  Interface::MethodType.new(
593
644
  type_params: [],
594
- params: Interface::Params.new(required: [AST::Types::Literal.new(value: index), elem_type],
595
- optional: [],
596
- rest: nil,
597
- required_keywords: {},
598
- optional_keywords: {},
599
- rest_keywords: nil),
645
+ type: Interface::Function.new(
646
+ params: Interface::Function::Params.new(required: [AST::Types::Literal.new(value: index), elem_type],
647
+ optional: [],
648
+ rest: nil,
649
+ required_keywords: {},
650
+ optional_keywords: {},
651
+ rest_keywords: nil),
652
+ return_type: elem_type,
653
+ location: nil
654
+ ),
600
655
  block: nil,
601
- return_type: elem_type,
602
656
  method_decls: Set[]
603
657
  )
604
658
  } + update.method_types
@@ -610,9 +664,12 @@ module Steep
610
664
  method_types: [
611
665
  Interface::MethodType.new(
612
666
  type_params: [],
613
- params: Interface::Params.empty,
667
+ type: Interface::Function.new(
668
+ params: Interface::Function::Params.empty,
669
+ return_type: type.types[0] || AST::Builtin.nil_type,
670
+ location: nil
671
+ ),
614
672
  block: nil,
615
- return_type: type.types[0] || AST::Builtin.nil_type,
616
673
  method_decls: Set[]
617
674
  )
618
675
  ]
@@ -624,9 +681,12 @@ module Steep
624
681
  method_types: [
625
682
  Interface::MethodType.new(
626
683
  type_params: [],
627
- params: Interface::Params.empty,
684
+ type: Interface::Function.new(
685
+ params: Interface::Function::Params.empty,
686
+ return_type: type.types.last || AST::Builtin.nil_type,
687
+ location: nil
688
+ ),
628
689
  block: nil,
629
- return_type: type.types.last || AST::Builtin.nil_type,
630
690
  method_decls: Set[]
631
691
  )
632
692
  ]
@@ -651,14 +711,17 @@ module Steep
651
711
 
652
712
  Interface::MethodType.new(
653
713
  type_params: [],
654
- params: Interface::Params.new(required: [key_type],
655
- optional: [],
656
- rest: nil,
657
- required_keywords: {},
658
- optional_keywords: {},
659
- rest_keywords: nil),
714
+ type: Interface::Function.new(
715
+ params: Interface::Function::Params.new(required: [key_type],
716
+ optional: [],
717
+ rest: nil,
718
+ required_keywords: {},
719
+ optional_keywords: {},
720
+ rest_keywords: nil),
721
+ return_type: value_type,
722
+ location: nil
723
+ ),
660
724
  block: nil,
661
- return_type: value_type,
662
725
  method_decls: Set[]
663
726
  )
664
727
  } + ref.method_types
@@ -671,14 +734,16 @@ module Steep
671
734
  key_type = Literal.new(value: key_value, location: nil)
672
735
  Interface::MethodType.new(
673
736
  type_params: [],
674
- params: Interface::Params.new(required: [key_type, value_type],
675
- optional: [],
676
- rest: nil,
677
- required_keywords: {},
678
- optional_keywords: {},
679
- rest_keywords: nil),
737
+ type: Interface::Function.new(
738
+ params: Interface::Function::Params.new(required: [key_type, value_type],
739
+ optional: [],
740
+ rest: nil,
741
+ required_keywords: {},
742
+ optional_keywords: {},
743
+ rest_keywords: nil),
744
+ return_type: value_type,
745
+ location: nil),
680
746
  block: nil,
681
- return_type: value_type,
682
747
  method_decls: Set[]
683
748
  )
684
749
  } + update.method_types
@@ -691,14 +756,18 @@ module Steep
691
756
  interface(Builtin::Proc.instance_type, private: private, self_type: self_type).tap do |interface|
692
757
  method_type = Interface::MethodType.new(
693
758
  type_params: [],
694
- params: type.params,
695
- return_type: type.return_type,
696
- block: nil,
759
+ type: type.type,
760
+ block: type.block,
697
761
  method_decls: Set[]
698
762
  )
699
763
 
700
- interface.methods[:[]] = Interface::Interface::Entry.new(method_types: [method_type])
701
764
  interface.methods[:call] = Interface::Interface::Entry.new(method_types: [method_type])
765
+
766
+ if type.block_required?
767
+ interface.methods.delete(:[])
768
+ else
769
+ interface.methods[:[]] = Interface::Interface::Entry.new(method_types: [method_type.with(block: nil)])
770
+ end
702
771
  end
703
772
 
704
773
  when Logic::Base
@@ -18,7 +18,7 @@ module Steep
18
18
  end
19
19
 
20
20
  def ==(other)
21
- other.class ==self.class
21
+ other.class == self.class
22
22
  end
23
23
 
24
24
  alias eql? ==
@@ -57,6 +57,38 @@ module Steep
57
57
  @location = location
58
58
  end
59
59
  end
60
+
61
+ class ArgEqualsReceiver < Base
62
+ def initialize(location: nil)
63
+ @location = location
64
+ end
65
+ end
66
+
67
+ class Env < Base
68
+ attr_reader :truthy, :falsy, :type
69
+
70
+ def initialize(truthy:, falsy:, type:, location: nil)
71
+ @truthy = truthy
72
+ @falsy = falsy
73
+ @type = type
74
+ end
75
+
76
+ def ==(other)
77
+ other.is_a?(Env) && other.truthy == truthy && other.falsy == falsy && other.type == type
78
+ end
79
+
80
+ alias eql? ==
81
+
82
+ def hash
83
+ self.class.hash ^ truthy.hash ^ falsy.hash
84
+ end
85
+
86
+ def inspect
87
+ "#<Steep::AST::Types::Env @type=#{type}, @truthy=..., @falsy=...>"
88
+ end
89
+
90
+ alias to_s inspect
91
+ end
60
92
  end
61
93
  end
62
94
  end
@@ -3,68 +3,76 @@ module Steep
3
3
  module Types
4
4
  class Proc
5
5
  attr_reader :location
6
- attr_reader :params
7
- attr_reader :return_type
6
+ attr_reader :type
7
+ attr_reader :block
8
8
 
9
- def initialize(params:, return_type:, location: nil)
9
+ def initialize(type:, block:, location: type.location)
10
+ @type = type
11
+ @block = block
10
12
  @location = location
11
- @params = params
12
- @return_type = return_type
13
13
  end
14
14
 
15
15
  def ==(other)
16
- other.is_a?(self.class) &&
17
- other.params == params &&
18
- other.return_type == return_type
16
+ other.is_a?(self.class) && other.type == type && other.block == block
19
17
  end
20
18
 
21
19
  def hash
22
- self.class.hash && params.hash && return_type.hash
20
+ self.class.hash ^ type.hash ^ block.hash
23
21
  end
24
22
 
25
23
  alias eql? ==
26
24
 
27
25
  def subst(s)
28
26
  self.class.new(
29
- params: params.subst(s),
30
- return_type: return_type.subst(s),
27
+ type: type.subst(s),
28
+ block: block&.subst(s),
31
29
  location: location
32
30
  )
33
31
  end
34
32
 
35
33
  def to_s
36
- "^#{params} -> #{return_type}"
34
+ if block
35
+ "^#{type.params} #{block} -> #{type.return_type}"
36
+ else
37
+ "^#{type.params} -> #{type.return_type}"
38
+ end
37
39
  end
38
40
 
39
41
  def free_variables()
40
- @fvs ||= Set.new.tap do |set|
41
- set.merge(params.free_variables)
42
- set.merge(return_type.free_variables)
42
+ @fvs ||= Set[].tap do |fvs|
43
+ fvs.merge(type.free_variables)
44
+ fvs.merge(block.free_variables) if block
43
45
  end
44
46
  end
45
47
 
46
48
  def level
47
- children = params.each_type.to_a + [return_type]
49
+ children = type.params.each_type.to_a + [type.return_type]
50
+ if block
51
+ children.push(*block.type.params.each_type.to_a)
52
+ children.push(block.type.return_type)
53
+ end
48
54
  [0] + level_of_children(children)
49
55
  end
50
56
 
51
57
  def closed?
52
- params.closed? && return_type.closed?
58
+ type.closed? && (block.nil? || block.closed?)
53
59
  end
54
60
 
55
61
  def with_location(new_location)
56
- self.class.new(location: new_location, params: params, return_type: return_type)
62
+ self.class.new(location: new_location, block: block, type: type)
57
63
  end
58
64
 
59
65
  def map_type(&block)
60
66
  self.class.new(
61
- params: params.map_type(&block),
62
- return_type: yield(return_type),
67
+ type: type.map_type(&block),
68
+ block: self.block&.map_type(&block),
63
69
  location: location
64
70
  )
65
71
  end
66
72
 
67
73
  def one_arg?
74
+ params = type.params
75
+
68
76
  params.required.size == 1 &&
69
77
  params.optional.empty? &&
70
78
  !params.rest &&
@@ -78,6 +86,10 @@ module Steep
78
86
  args: [],
79
87
  location: location)
80
88
  end
89
+
90
+ def block_required?
91
+ block && !block.optional?
92
+ end
81
93
  end
82
94
  end
83
95
  end