steep 1.1.1 → 1.2.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 (140) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +20 -0
  3. data/Gemfile +0 -1
  4. data/Gemfile.lock +12 -11
  5. data/Gemfile.steep +1 -1
  6. data/Gemfile.steep.lock +9 -9
  7. data/README.md +3 -3
  8. data/Steepfile +23 -0
  9. data/bin/steep-prof +2 -1
  10. data/lib/steep/annotation_parser.rb +1 -1
  11. data/lib/steep/ast/types/class.rb +4 -0
  12. data/lib/steep/ast/types/factory.rb +86 -602
  13. data/lib/steep/ast/types/instance.rb +4 -0
  14. data/lib/steep/ast/types/literal.rb +1 -1
  15. data/lib/steep/ast/types/proc.rb +22 -8
  16. data/lib/steep/ast/types/self.rb +4 -0
  17. data/lib/steep/ast/types/union.rb +1 -1
  18. data/lib/steep/cli.rb +24 -1
  19. data/lib/steep/diagnostic/ruby.rb +17 -22
  20. data/lib/steep/drivers/checkfile.rb +205 -0
  21. data/lib/steep/drivers/validate.rb +3 -1
  22. data/lib/steep/equatable.rb +2 -0
  23. data/lib/steep/interface/block.rb +21 -11
  24. data/lib/steep/interface/builder.rb +756 -0
  25. data/lib/steep/interface/function.rb +32 -24
  26. data/lib/steep/interface/method_type.rb +191 -78
  27. data/lib/steep/interface/shape.rb +132 -0
  28. data/lib/steep/interface/substitution.rb +23 -12
  29. data/lib/steep/interface/type_param.rb +1 -2
  30. data/lib/steep/path_helper.rb +1 -1
  31. data/lib/steep/project.rb +5 -7
  32. data/lib/steep/server/base_worker.rb +2 -2
  33. data/lib/steep/server/change_buffer.rb +4 -3
  34. data/lib/steep/server/interaction_worker.rb +1 -1
  35. data/lib/steep/server/master.rb +69 -9
  36. data/lib/steep/server/type_check_worker.rb +13 -11
  37. data/lib/steep/server/worker_process.rb +9 -7
  38. data/lib/steep/services/completion_provider.rb +15 -3
  39. data/lib/steep/services/hover_provider/singleton_methods.rb +5 -6
  40. data/lib/steep/services/signature_service.rb +13 -8
  41. data/lib/steep/services/type_check_service.rb +2 -0
  42. data/lib/steep/signature/validator.rb +1 -1
  43. data/lib/steep/subtyping/check.rb +154 -103
  44. data/lib/steep/subtyping/relation.rb +3 -3
  45. data/lib/steep/subtyping/result.rb +20 -2
  46. data/lib/steep/subtyping/variable_variance.rb +9 -0
  47. data/lib/steep/type_construction.rb +558 -299
  48. data/lib/steep/type_inference/block_params.rb +169 -86
  49. data/lib/steep/type_inference/logic_type_interpreter.rb +9 -14
  50. data/lib/steep/type_inference/method_params.rb +12 -7
  51. data/lib/steep/type_inference/send_args.rb +41 -35
  52. data/lib/steep/type_inference/type_env_builder.rb +1 -1
  53. data/lib/steep/version.rb +1 -1
  54. data/lib/steep.rb +71 -2
  55. data/rbs_collection.steep.lock.yaml +18 -30
  56. data/rbs_collection.steep.yaml +1 -0
  57. data/sig/shims/language-server_protocol.rbs +20 -0
  58. data/sig/shims/tagged_logging.rbs +6 -0
  59. data/sig/steep/ast/annotation/collection.rbs +6 -6
  60. data/sig/steep/ast/types/class.rbs +3 -0
  61. data/sig/steep/ast/types/factory.rbs +38 -32
  62. data/sig/steep/ast/types/instance.rbs +3 -0
  63. data/sig/steep/ast/types/intersection.rbs +1 -1
  64. data/sig/steep/ast/types/literal.rbs +7 -7
  65. data/sig/steep/ast/types/name.rbs +14 -13
  66. data/sig/steep/ast/types/proc.rbs +3 -1
  67. data/sig/steep/ast/types/self.rbs +3 -0
  68. data/sig/steep/ast/types/var.rbs +1 -1
  69. data/sig/steep/diagnostic/ruby.rbs +30 -34
  70. data/sig/steep/drivers/annotations.rbs +17 -0
  71. data/sig/steep/drivers/check.rbs +33 -0
  72. data/sig/steep/drivers/checkfile.rbs +26 -0
  73. data/sig/steep/drivers/diagnostic_printer.rbs +25 -0
  74. data/sig/steep/drivers/init.rbs +19 -0
  75. data/sig/steep/drivers/langserver.rbs +35 -0
  76. data/sig/steep/drivers/print_project.rbs +15 -0
  77. data/sig/steep/drivers/stats.rbs +37 -0
  78. data/sig/steep/drivers/utils/driver_helper.rbs +23 -0
  79. data/sig/steep/drivers/utils/jobs_count.rbs +11 -0
  80. data/sig/steep/drivers/validate.rbs +15 -0
  81. data/sig/steep/drivers/vendor.rbs +19 -0
  82. data/sig/steep/drivers/watch.rbs +27 -0
  83. data/sig/steep/drivers/worker.rbs +31 -0
  84. data/sig/steep/equatable.rbs +11 -0
  85. data/sig/steep/index/rbs_index.rbs +91 -0
  86. data/sig/steep/index/signature_symbol_provider.rbs +29 -0
  87. data/sig/steep/index/source_index.rbs +63 -0
  88. data/sig/steep/interface/block.rbs +3 -1
  89. data/sig/steep/interface/builder.rbs +152 -0
  90. data/sig/steep/interface/function.rbs +67 -55
  91. data/sig/steep/interface/method_type.rbs +60 -12
  92. data/sig/steep/interface/shape.rbs +61 -0
  93. data/sig/steep/interface/substitution.rbs +18 -22
  94. data/sig/steep/interface/type_param.rbs +9 -1
  95. data/sig/steep/path_helper.rbs +7 -0
  96. data/sig/steep/project/pattern.rbs +10 -10
  97. data/sig/steep/project/target.rbs +2 -2
  98. data/sig/steep/project.rbs +15 -8
  99. data/sig/steep/server/base_worker.rbs +49 -0
  100. data/sig/steep/server/change_buffer.rbs +32 -0
  101. data/sig/steep/server/interaction_worker.rbs +41 -0
  102. data/sig/steep/server/lsp_formatter.rbs +29 -0
  103. data/sig/steep/server/master.rbs +260 -0
  104. data/sig/steep/server/type_check_worker.rbs +135 -0
  105. data/sig/steep/server/worker_process.rbs +29 -0
  106. data/sig/steep/services/completion_provider.rbs +5 -5
  107. data/sig/steep/services/content_change.rbs +14 -12
  108. data/sig/steep/services/file_loader.rbs +12 -4
  109. data/sig/steep/services/hover_provider/singleton_methods.rbs +1 -1
  110. data/sig/steep/services/path_assignment.rbs +7 -7
  111. data/sig/steep/services/signature_service.rbs +67 -40
  112. data/sig/steep/services/type_check_service.rbs +53 -39
  113. data/sig/steep/subtyping/check.rbs +80 -44
  114. data/sig/steep/subtyping/relation.rbs +24 -22
  115. data/sig/steep/subtyping/result.rbs +48 -30
  116. data/sig/steep/subtyping/variable_variance.rbs +2 -0
  117. data/sig/steep/type_construction.rbs +132 -23
  118. data/sig/steep/type_inference/block_params.rbs +120 -18
  119. data/sig/steep/type_inference/context.rbs +45 -20
  120. data/sig/steep/type_inference/context_array.rbs +37 -0
  121. data/sig/steep/type_inference/logic_type_interpreter.rbs +3 -1
  122. data/sig/steep/type_inference/method_params.rbs +13 -9
  123. data/sig/steep/type_inference/send_args.rbs +229 -0
  124. data/sig/steep/type_inference/type_env_builder.rbs +1 -1
  125. data/sig/steep/typing.rbs +4 -4
  126. data/sig/steep.rbs +4 -2
  127. data/smoke/block/e.rb +12 -0
  128. data/smoke/block/e.rbs +4 -0
  129. data/smoke/block/test_expectations.yml +12 -0
  130. data/smoke/regression/block_param_split.rb +7 -0
  131. data/smoke/regression/block_param_split.rbs +3 -0
  132. data/smoke/regression/empty_yield.rb +5 -0
  133. data/smoke/regression/empty_yield.rbs +3 -0
  134. data/smoke/regression/test_expectations.yml +12 -0
  135. data/smoke/yield/test_expectations.yml +4 -4
  136. data/steep.gemspec +2 -1
  137. metadata +61 -9
  138. data/lib/steep/interface/interface.rb +0 -34
  139. data/sig/steep/interface/interface.rbs +0 -23
  140. data/sig/version.rbs +0 -3
@@ -37,7 +37,7 @@ module Steep
37
37
  if ty == type
38
38
  self
39
39
  else
40
- self.class.new(ty)
40
+ _ = self.class.new(ty)
41
41
  end
42
42
  end
43
43
 
@@ -47,7 +47,7 @@ module Steep
47
47
 
48
48
  def map_type(&block)
49
49
  if block_given?
50
- self.class.new(yield type)
50
+ _ = self.class.new(yield type)
51
51
  else
52
52
  enum_for(:map_type)
53
53
  end
@@ -94,7 +94,7 @@ module Steep
94
94
  end
95
95
 
96
96
  def map_type(&block)
97
- if block_given?
97
+ if block
98
98
  map {|param| param.map_type(&block) }
99
99
  else
100
100
  enum_for :map_type
@@ -123,7 +123,7 @@ module Steep
123
123
  end
124
124
 
125
125
  def each(&block)
126
- if block_given?
126
+ if block
127
127
  yield head
128
128
  tail&.each(&block)
129
129
  else
@@ -411,11 +411,11 @@ module Steep
411
411
  end
412
412
 
413
413
  def each(&block)
414
- if block_given?
414
+ if block
415
415
  requireds.each(&block)
416
416
  optionals.each(&block)
417
417
  if rest
418
- yield nil, rest
418
+ yield [nil, rest]
419
419
  end
420
420
  else
421
421
  enum_for :each
@@ -433,7 +433,7 @@ module Steep
433
433
  end
434
434
 
435
435
  def map_type(&block)
436
- if block_given?
436
+ if block
437
437
  rs = requireds.transform_values(&block)
438
438
  os = optionals.transform_values(&block)
439
439
  r = rest&.yield_self(&block)
@@ -819,7 +819,7 @@ module Steep
819
819
  end
820
820
 
821
821
  def each_type(&block)
822
- if block_given?
822
+ if block
823
823
  positional_params&.each_type(&block)
824
824
  keyword_params.each_type(&block)
825
825
  else
@@ -842,16 +842,19 @@ module Steep
842
842
  def subst(s)
843
843
  return self if s.empty?
844
844
  return self if empty?
845
- return self if free_variables.disjoint?(s.domain)
845
+ return self if each_type.none? {|t| s.apply?(t) }
846
846
 
847
- pp = positional_params&.subst(s)
848
- kp = keyword_params.subst(s)
847
+ pp = positional_params
848
+ kp = keyword_params
849
849
 
850
- if positional_params == pp && keyword_params == kp
851
- self
852
- else
853
- self.class.new(positional_params: pp, keyword_params: kp)
850
+ if positional_params && positional_params.each_type.any? {|t| s.apply?(t) }
851
+ pp = positional_params.subst(s)
854
852
  end
853
+ if keyword_params && keyword_params.each_type.any? {|t| s.apply?(t) }
854
+ kp = keyword_params.subst(s)
855
+ end
856
+
857
+ self.class.new(positional_params: pp, keyword_params: kp)
855
858
  end
856
859
 
857
860
  def size
@@ -950,19 +953,22 @@ module Steep
950
953
  def subst(s)
951
954
  return self if s.empty?
952
955
 
953
- Function.new(
954
- params: params.subst(s),
955
- return_type: return_type.subst(s),
956
- location: location
957
- )
958
- end
956
+ ps = params.subst(s)
957
+ ret = return_type.subst(s)
959
958
 
960
- def each_child(&block)
961
- each_type(&block)
959
+ if ps == params && ret == return_type
960
+ self
961
+ else
962
+ Function.new(
963
+ params: ps,
964
+ return_type: ret,
965
+ location: location
966
+ )
967
+ end
962
968
  end
963
969
 
964
970
  def each_type(&block)
965
- if block_given?
971
+ if block
966
972
  params.each_type(&block)
967
973
  yield return_type
968
974
  else
@@ -970,6 +976,8 @@ module Steep
970
976
  end
971
977
  end
972
978
 
979
+ alias each_child each_type
980
+
973
981
  def map_type(&block)
974
982
  Function.new(
975
983
  params: params.map_type(&block),
@@ -32,30 +32,37 @@ module Steep
32
32
  if block
33
33
  set.merge(block.free_variables)
34
34
  end
35
- set.subtract(type_params)
35
+ set.subtract(type_params.map(&:name))
36
36
  end
37
37
  end
38
38
 
39
39
  def subst(s)
40
40
  return self if s.empty?
41
- return self if free_variables.disjoint?(s.domain)
41
+ return self if each_type.none? {|t| s.apply?(t) }
42
42
 
43
- s_ = s.except(type_params)
43
+ if type_params.any? {|param| s.key?(param.name) }
44
+ s_ = s.except(type_params.map(&:name))
45
+ else
46
+ s_ = s
47
+ end
44
48
 
45
- self.class.new(
46
- type_params: type_params,
47
- type: type.subst(s_),
48
- block: block&.subst(s_),
49
- method_decls: method_decls
50
- )
49
+ ty = type.subst(s_)
50
+ bl = block&.subst(s_)
51
+
52
+ if ty == type && bl == block
53
+ self
54
+ else
55
+ self.class.new(type_params: type_params, type: ty, block: bl, method_decls: method_decls)
56
+ end
51
57
  end
52
58
 
53
59
  def each_type(&block)
54
- if block_given?
60
+ if block
55
61
  type.each_type(&block)
56
- self.block&.tap do
57
- self.block.type.params.each_type(&block)
58
- yield(self.block.type.return_type)
62
+ if block()
63
+ yield(block().self_type) if block().self_type
64
+ block().type.params.each_type(&block)
65
+ yield(block().type.return_type)
59
66
  end
60
67
  else
61
68
  enum_for :each_type
@@ -99,14 +106,15 @@ module Steep
99
106
  type_params_2, s2 = TypeParam.rename(other.type_params)
100
107
  type_params = type_params_1 + type_params_2
101
108
 
102
- block = case
103
- when self.block && other.block
104
- self.block.subst(s1) + other.block.subst(s2)
105
- when self.block
106
- self.block.to_optional.subst(s1)
107
- when other.block
108
- other.block.to_optional.subst(s2)
109
- end
109
+ block =
110
+ case
111
+ when (b = self.block) && (ob = other.block)
112
+ b.subst(s1) + ob.subst(s2)
113
+ when b = self.block
114
+ b.to_optional.subst(s1)
115
+ when ob = other.block
116
+ ob.to_optional.subst(s2)
117
+ end
110
118
 
111
119
  self.class.new(
112
120
  type_params: type_params,
@@ -126,82 +134,187 @@ module Steep
126
134
  unify_overload(other)
127
135
  end
128
136
 
129
- # Returns a method type which is a super-type of both self and other.
130
- # self <: (self | other) && other <: (self | other)
131
- #
132
- # Returns nil if self and other are incompatible.
133
- #
134
- def |(other)
135
- if other.type_params.empty?
136
- type_params = self.type_params
137
+ def equals_modulo_type_params?(other)
138
+ case
139
+ when self.type_params.empty? && other.type_params.empty?
140
+ self == other
141
+ when self.type_params.size == other.type_params.size
142
+ new_names = self.type_params.map(&:name)
143
+
144
+ self_params, self_subst = TypeParam.rename(self.type_params, self.type_params.map(&:name), new_names)
145
+ other_params, other_subst = TypeParam.rename(other.type_params, other.type_params.map(&:name), new_names)
146
+
147
+ self_params == other_params && self.instantiate(self_subst) == other.instantiate(other_subst)
137
148
  else
138
- other_params, s2 = TypeParam.rename(other.type_params)
139
- other = other.instantiate(s2)
140
- type_params = self.type_params + other_params
149
+ false
141
150
  end
151
+ end
142
152
 
143
- params = self.type.params & other.type.params or return
144
- block = case
145
- when self.block && other.block
146
- block_params = self.block.type.params | other.block.type.params
147
- block_return_type = AST::Types::Intersection.build(types: [self.block.type.return_type, other.block.type.return_type])
148
- block_type = Function.new(params: block_params, return_type: block_return_type, location: nil)
149
- Block.new(
150
- type: block_type,
151
- optional: self.block.optional && other.block.optional
152
- )
153
- when self.block && self.block.optional?
154
- self.block
155
- when other.block && other.block.optional?
156
- other.block
157
- when !self.block && !other.block
158
- nil
159
- else
160
- return
153
+ def self.union(type1, type2, check)
154
+ try_type_params(
155
+ type1,
156
+ type2,
157
+ check,
158
+ -> (t1, t2) { t1 | t2 },
159
+ -> (original, generated) { Subtyping::Relation.new(sub_type: original, super_type: generated) }
160
+ )
161
+ end
162
+
163
+ def self.intersection(type1, type2, check)
164
+ try_type_params(
165
+ type1,
166
+ type2,
167
+ check,
168
+ -> (t1, t2) { t1 & t2 },
169
+ -> (original, generated) { Subtyping::Relation.new(sub_type: generated, super_type: original) }
170
+ )
171
+ end
172
+
173
+ def self.try_type_params(type1, type2, check, generate, relation)
174
+ return type1 if type1.equals_modulo_type_params?(type2)
175
+
176
+ case
177
+ when type1.type_params.empty? && type2.type_params.empty?
178
+ generate[type1, type2]
179
+ when type1.type_params.empty?
180
+ if mt = generate[type1, type2.with(type_params: [])]
181
+ mt.with(type_params: type2.type_params)
182
+ end
183
+ when type2.type_params.empty?
184
+ if mt = generate[type1.with(type_params: []), type2]
185
+ mt.with(type_params: type1.type_params)
186
+ end
187
+ when type1.type_params.size == type2.type_params.size
188
+ params1, s1 = TypeParam.rename(type1.type_params)
189
+ params2, s2 = TypeParam.rename(type2.type_params)
190
+
191
+ type1_ = type1.instantiate(s1)
192
+ type2_ = type2.instantiate(s2)
193
+ if mt = generate[type1_, type2_]
194
+ check.push_variable_bounds(params1 + params2) do
195
+ variables = type1.type_params.map(&:name) + type2.type_params.map(&:name)
196
+ constraints = Subtyping::Constraints.new(unknowns: variables)
197
+
198
+ check.with_context(self_type: AST::Builtin.any_type, instance_type: AST::Builtin.any_type, class_type: AST::Builtin.any_type, constraints: constraints) do
199
+ result1 = check.check_method_type(:__method_on_type1, relation[type1.with(type_params: []), mt])
200
+ result2 = check.check_method_type(:__method_on_type2, relation[type2.with(type_params: []), mt])
201
+
202
+ if result1.success? && result2.success?
203
+ unless type1.type_params.map(&:name).zip(type2.type_params.map(&:name)).all? {|pair|
204
+ constraints.upper_bound(pair[0]) == constraints.upper_bound(pair[1] || raise) &&
205
+ constraints.lower_bound(pair[0]) == constraints.lower_bound(pair[1] || raise)
206
+ }
207
+ return
208
+ end
209
+
210
+ params2_, s2_ = TypeParam.rename(type2.type_params, type2.type_params.map(&:name), type1.type_params.map(&:name))
211
+ if mt_ = generate[type1.with(type_params: []), type2.instantiate(s2_)]
212
+ mt_.with(
213
+ type_params: type1.type_params.map.with_index {|param1, index|
214
+ param2 = params2_[index] or raise
215
+ ub1 = param1.upper_bound
216
+ ub2 = param2.upper_bound
217
+
218
+ case
219
+ when ub1 && ub2
220
+ param1.update(upper_bound: AST::Types::Union.build(types: [ub1, ub2]))
221
+ when ub2
222
+ param1.update(upper_bound: ub2)
223
+ else
224
+ param1
225
+ end
226
+ }
227
+ )
228
+ end
161
229
  end
230
+ end
231
+ end
232
+ end
233
+ end
234
+ end
235
+
236
+ def |(other)
237
+ return self if other == self
238
+
239
+ params = self.type.params & other.type.params or return
240
+ block =
241
+ case
242
+ when (b = block()) && (ob = other.block)
243
+ self_type =
244
+ case
245
+ when (self_self = b.self_type) && (other_self = ob.self_type)
246
+ AST::Types::Union.build(types: [self_self, other_self])
247
+ when b.self_type || ob.self_type
248
+ AST::Types::Bot.new()
249
+ else
250
+ nil
251
+ end
252
+
253
+ # Return when the two block parameters are imcompatible.
254
+ return unless b.type.params & ob.type.params
255
+
256
+ block_params = b.type.params | ob.type.params or return
257
+
258
+ block_return_type = AST::Types::Intersection.build(types: [b.type.return_type, ob.type.return_type])
259
+ block_type = Function.new(params: block_params, return_type: block_return_type, location: nil)
260
+
261
+ Block.new(
262
+ type: block_type,
263
+ optional: b.optional && ob.optional,
264
+ self_type: self_type
265
+ )
266
+ when (b = block()) && b.optional?
267
+ b
268
+ when other.block && other.block.optional?
269
+ other.block
270
+ when !self.block && !other.block
271
+ nil
272
+ else
273
+ return
274
+ end
162
275
  return_type = AST::Types::Union.build(types: [self.type.return_type, other.type.return_type])
163
276
 
164
277
  MethodType.new(
165
- type_params: type_params,
278
+ type_params: [],
166
279
  type: Function.new(params: params, return_type: return_type, location: nil),
167
280
  block: block,
168
281
  method_decls: method_decls + other.method_decls
169
282
  )
170
283
  end
171
284
 
172
- # Returns a method type which is a sub-type of both self and other.
173
- # (self & other) <: self && (self & other) <: other
174
- #
175
- # Returns nil if self and other are incompatible.
176
- #
177
285
  def &(other)
178
- if other.type_params.empty?
179
- type_params = self.type_params
180
- else
181
- other_params, s2 = TypeParam.rename(other.type_params)
182
- other = other.instantiate(s2)
183
- type_params = self.type_params + other_params
184
- end
286
+ return self if self == other
185
287
 
186
- params = self.type.params | other.type.params
187
- block = case
188
- when self.block && other.block
189
- block_params = self.block.type.params & other.block.type.params or return
190
- block_return_type = AST::Types::Union.build(types: [self.block.type.return_type, other.block.type.return_type])
191
- block_type = Function.new(params: block_params, return_type: block_return_type, location: nil)
192
- Block.new(
193
- type: block_type,
194
- optional: self.block.optional || other.block.optional
195
- )
196
-
197
- else
198
- self.block || other.block
199
- end
288
+ params = self.type.params | other.type.params or return
289
+ block =
290
+ case
291
+ when (b = self.block) && (ob = other.block)
292
+ self_type =
293
+ case
294
+ when (self_self = b.self_type) && (other_self = ob.self_type)
295
+ AST::Types::Intersection.build(types: [self_self, other_self])
296
+ when b.self_type || ob.self_type
297
+ AST::Types::Top.new()
298
+ else
299
+ nil
300
+ end
301
+
302
+ block_params = b.type.params & ob.type.params or return
303
+ block_return_type = AST::Types::Union.build(types: [b.type.return_type, ob.type.return_type])
304
+ block_type = Function.new(params: block_params, return_type: block_return_type, location: nil)
305
+ Block.new(
306
+ type: block_type,
307
+ optional: b.optional || ob.optional,
308
+ self_type: self_type
309
+ )
310
+ else
311
+ self.block || other.block
312
+ end
200
313
 
201
314
  return_type = AST::Types::Intersection.build(types: [self.type.return_type, other.type.return_type])
202
315
 
203
316
  MethodType.new(
204
- type_params: type_params,
317
+ type_params: [],
205
318
  type: Function.new(params: params, return_type: return_type, location: nil),
206
319
  block: block,
207
320
  method_decls: method_decls + other.method_decls
@@ -0,0 +1,132 @@
1
+ module Steep
2
+ module Interface
3
+ class Shape
4
+ class Entry
5
+ attr_reader :method_types
6
+
7
+ def initialize(method_types:)
8
+ @method_types = method_types
9
+ end
10
+
11
+ def to_s
12
+ "{ #{method_types.join(" || ")} }"
13
+ end
14
+ end
15
+
16
+ class Methods
17
+ attr_reader :substs, :methods, :resolved_methods
18
+
19
+ include Enumerable
20
+
21
+ def initialize(substs:, methods:)
22
+ @substs = substs
23
+ @methods = methods
24
+ @resolved_methods = methods.transform_values { nil }
25
+ end
26
+
27
+ def key?(name)
28
+ methods.key?(name)
29
+ end
30
+
31
+ def []=(name, entry)
32
+ resolved_methods[name] = nil
33
+ methods[name] = entry
34
+ end
35
+
36
+ def [](name)
37
+ return nil unless key?(name)
38
+
39
+ resolved_methods[name] ||= begin
40
+ Entry.new(
41
+ method_types: methods[name].method_types.map do |method_type|
42
+ method_type.subst(subst)
43
+ end
44
+ )
45
+ end
46
+ end
47
+
48
+ def each(&block)
49
+ if block
50
+ methods.each_key do |name|
51
+ entry = self[name] or raise
52
+ yield [name, entry]
53
+ end
54
+ else
55
+ enum_for :each
56
+ end
57
+ end
58
+
59
+ def each_name(&block)
60
+ if block
61
+ methods.each_key(&block)
62
+ else
63
+ enum_for :each_name
64
+ end
65
+ end
66
+
67
+ def subst
68
+ @subst ||= begin
69
+ substs.each_with_object(Substitution.empty) do |s, ss|
70
+ ss.merge!(s, overwrite: true)
71
+ end
72
+ end
73
+ end
74
+
75
+ def push_substitution(subst)
76
+ Methods.new(substs: [*substs, subst], methods: methods)
77
+ end
78
+
79
+ def merge!(other)
80
+ other.each do |name, entry|
81
+ methods[name] = entry
82
+ end
83
+ end
84
+
85
+ def +(other)
86
+ methods = Methods.new(substs: [], methods: {})
87
+
88
+ methods.merge!(self)
89
+ methods.merge!(other)
90
+
91
+ methods
92
+ end
93
+ end
94
+
95
+ attr_reader :type
96
+ attr_reader :methods
97
+
98
+ def initialize(type:, private:, methods: nil)
99
+ @type = type
100
+ @private = private
101
+ @methods = methods || Methods.new(substs: [], methods: {})
102
+ end
103
+
104
+ def to_s
105
+ "#<#{self.class.name}: type=#{type}, private?=#{@private}, methods={#{methods.each_name.sort.join(", ")}}"
106
+ end
107
+
108
+ def update(type: self.type, methods: self.methods)
109
+ _ = self.class.new(type: type, private: private?, methods: methods)
110
+ end
111
+
112
+ def subst(s, type: nil)
113
+ ty =
114
+ if type
115
+ type
116
+ else
117
+ self.type.subst(s)
118
+ end
119
+
120
+ Shape.new(type: ty, private: private?, methods: methods.push_substitution(s))
121
+ end
122
+
123
+ def private?
124
+ @private
125
+ end
126
+
127
+ def public?
128
+ !private?
129
+ end
130
+ end
131
+ end
132
+ end
@@ -27,9 +27,9 @@ module Steep
27
27
 
28
28
  def self.empty
29
29
  new(dictionary: {},
30
- instance_type: INSTANCE_TYPE,
31
- module_type: CLASS_TYPE,
32
- self_type: SELF_TYPE)
30
+ instance_type: AST::Types::Instance.instance,
31
+ module_type: AST::Types::Class.instance,
32
+ self_type: AST::Types::Self.instance)
33
33
  end
34
34
 
35
35
  def empty?
@@ -39,17 +39,13 @@ module Steep
39
39
  self_type.is_a?(AST::Types::Self)
40
40
  end
41
41
 
42
- INSTANCE_TYPE = AST::Types::Instance.new
43
- CLASS_TYPE = AST::Types::Class.new
44
- SELF_TYPE = AST::Types::Self.new
45
-
46
42
  def domain
47
43
  set = Set.new
48
44
 
49
45
  set.merge(dictionary.keys)
50
- set << INSTANCE_TYPE unless instance_type.is_a?(AST::Types::Instance)
51
- set << CLASS_TYPE unless instance_type.is_a?(AST::Types::Class)
52
- set << SELF_TYPE unless instance_type.is_a?(AST::Types::Self)
46
+ set << AST::Types::Instance.instance unless instance_type.is_a?(AST::Types::Instance)
47
+ set << AST::Types::Class.instance unless instance_type.is_a?(AST::Types::Class)
48
+ set << AST::Types::Instance.instance unless instance_type.is_a?(AST::Types::Self)
53
49
 
54
50
  set
55
51
  end
@@ -76,7 +72,22 @@ module Steep
76
72
  dictionary.key?(var)
77
73
  end
78
74
 
79
- def self.build(vars, types = nil, instance_type: AST::Types::Instance.new, module_type: AST::Types::Class.new, self_type: AST::Types::Self.new)
75
+ def apply?(type)
76
+ case type
77
+ when AST::Types::Var
78
+ key?(type.name)
79
+ when AST::Types::Self
80
+ !self_type.is_a?(AST::Types::Self)
81
+ when AST::Types::Instance
82
+ !instance_type.is_a?(AST::Types::Instance)
83
+ when AST::Types::Class
84
+ !module_type.is_a?(AST::Types::Class)
85
+ else
86
+ type.each_child.any? {|t| apply?(t) }
87
+ end
88
+ end
89
+
90
+ def self.build(vars, types = nil, instance_type: AST::Types::Instance.instance, module_type: AST::Types::Class.instance, self_type: AST::Types::Self.instance)
80
91
  types ||= vars.map {|var| AST::Types::Var.fresh(var) }
81
92
 
82
93
  raise InvalidSubstitutionError.new(vars_size: vars.size, types_size: types.size) unless vars.size == types.size
@@ -90,7 +101,7 @@ module Steep
90
101
 
91
102
  def except(vars)
92
103
  self.class.new(
93
- dictionary: dictionary,
104
+ dictionary: dictionary.dup,
94
105
  instance_type: instance_type,
95
106
  module_type: module_type,
96
107
  self_type: self_type
@@ -29,9 +29,8 @@ module Steep
29
29
  name.hash ^ upper_bound.hash ^ variance.hash ^ unchecked.hash
30
30
  end
31
31
 
32
- def self.rename(params, conflicting_names = params.map(&:name))
32
+ def self.rename(params, conflicting_names = params.map(&:name), new_names = conflicting_names.map {|n| AST::Types::Var.fresh_name(n) })
33
33
  unless conflicting_names.empty?
34
- new_names = conflicting_names.map {|n| AST::Types::Var.fresh_name(n) }
35
34
  hash = conflicting_names.zip(new_names).to_h
36
35
  new_types = new_names.map {|n| AST::Types::Var.new(name: n) }
37
36
 
@@ -5,7 +5,7 @@ module Steep
5
5
  def to_pathname(uri, dosish: Gem.win_platform?)
6
6
  uri = URI.parse(uri)
7
7
  if uri.scheme == "file"
8
- path = uri.path
8
+ path = uri.path or raise
9
9
  path.sub!(%r{^/([a-zA-Z])(:|%3A)//?}i, '\1:/') if dosish
10
10
  Pathname(path)
11
11
  end