steep 0.1.0.pre2 → 0.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.
Files changed (119) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +1 -1
  3. data/README.md +146 -33
  4. data/bin/smoke_runner.rb +43 -10
  5. data/lib/steep/ast/annotation/collection.rb +93 -0
  6. data/lib/steep/ast/annotation.rb +131 -0
  7. data/lib/steep/ast/buffer.rb +47 -0
  8. data/lib/steep/ast/location.rb +82 -0
  9. data/lib/steep/ast/method_type.rb +116 -0
  10. data/lib/steep/ast/signature/class.rb +33 -0
  11. data/lib/steep/ast/signature/const.rb +17 -0
  12. data/lib/steep/ast/signature/env.rb +123 -0
  13. data/lib/steep/ast/signature/extension.rb +21 -0
  14. data/lib/steep/ast/signature/gvar.rb +17 -0
  15. data/lib/steep/ast/signature/interface.rb +31 -0
  16. data/lib/steep/ast/signature/members.rb +71 -0
  17. data/lib/steep/ast/signature/module.rb +21 -0
  18. data/lib/steep/ast/type_params.rb +13 -0
  19. data/lib/steep/ast/types/any.rb +39 -0
  20. data/lib/steep/ast/types/bot.rb +39 -0
  21. data/lib/steep/ast/types/class.rb +35 -0
  22. data/lib/steep/ast/types/helper.rb +21 -0
  23. data/lib/steep/ast/types/instance.rb +39 -0
  24. data/lib/steep/ast/types/intersection.rb +74 -0
  25. data/lib/steep/ast/types/name.rb +124 -0
  26. data/lib/steep/ast/types/self.rb +39 -0
  27. data/lib/steep/ast/types/top.rb +39 -0
  28. data/lib/steep/ast/types/union.rb +74 -0
  29. data/lib/steep/ast/types/var.rb +57 -0
  30. data/lib/steep/ast/types/void.rb +35 -0
  31. data/lib/steep/cli.rb +28 -1
  32. data/lib/steep/drivers/annotations.rb +32 -0
  33. data/lib/steep/drivers/check.rb +53 -77
  34. data/lib/steep/drivers/scaffold.rb +303 -0
  35. data/lib/steep/drivers/utils/each_signature.rb +66 -0
  36. data/lib/steep/drivers/utils/validator.rb +115 -0
  37. data/lib/steep/drivers/validate.rb +39 -0
  38. data/lib/steep/errors.rb +291 -19
  39. data/lib/steep/interface/abstract.rb +44 -0
  40. data/lib/steep/interface/builder.rb +470 -0
  41. data/lib/steep/interface/instantiated.rb +126 -0
  42. data/lib/steep/interface/ivar_chain.rb +26 -0
  43. data/lib/steep/interface/method.rb +60 -0
  44. data/lib/steep/{interface.rb → interface/method_type.rb} +111 -100
  45. data/lib/steep/interface/substitution.rb +65 -0
  46. data/lib/steep/module_name.rb +116 -0
  47. data/lib/steep/parser.rb +1314 -814
  48. data/lib/steep/parser.y +536 -175
  49. data/lib/steep/source.rb +220 -25
  50. data/lib/steep/subtyping/check.rb +673 -0
  51. data/lib/steep/subtyping/constraints.rb +275 -0
  52. data/lib/steep/subtyping/relation.rb +41 -0
  53. data/lib/steep/subtyping/result.rb +126 -0
  54. data/lib/steep/subtyping/trace.rb +48 -0
  55. data/lib/steep/subtyping/variable_occurrence.rb +49 -0
  56. data/lib/steep/subtyping/variable_variance.rb +69 -0
  57. data/lib/steep/type_construction.rb +1630 -524
  58. data/lib/steep/type_inference/block_params.rb +100 -0
  59. data/lib/steep/type_inference/constant_env.rb +55 -0
  60. data/lib/steep/type_inference/send_args.rb +222 -0
  61. data/lib/steep/type_inference/type_env.rb +226 -0
  62. data/lib/steep/type_name.rb +27 -7
  63. data/lib/steep/typing.rb +4 -0
  64. data/lib/steep/version.rb +1 -1
  65. data/lib/steep.rb +71 -16
  66. data/smoke/and/a.rb +4 -2
  67. data/smoke/array/a.rb +4 -5
  68. data/smoke/array/b.rb +4 -4
  69. data/smoke/block/a.rb +2 -2
  70. data/smoke/block/a.rbi +2 -0
  71. data/smoke/block/b.rb +15 -0
  72. data/smoke/case/a.rb +3 -3
  73. data/smoke/class/a.rb +3 -3
  74. data/smoke/class/b.rb +0 -2
  75. data/smoke/class/d.rb +2 -2
  76. data/smoke/class/e.rb +1 -1
  77. data/smoke/class/f.rb +2 -2
  78. data/smoke/class/g.rb +8 -0
  79. data/smoke/const/a.rb +3 -3
  80. data/smoke/dstr/a.rb +1 -1
  81. data/smoke/ensure/a.rb +22 -0
  82. data/smoke/enumerator/a.rb +6 -6
  83. data/smoke/enumerator/b.rb +22 -0
  84. data/smoke/extension/a.rb +2 -2
  85. data/smoke/extension/b.rb +3 -3
  86. data/smoke/extension/c.rb +1 -1
  87. data/smoke/hello/hello.rb +2 -2
  88. data/smoke/if/a.rb +4 -2
  89. data/smoke/kwbegin/a.rb +8 -0
  90. data/smoke/literal/a.rb +5 -5
  91. data/smoke/method/a.rb +5 -5
  92. data/smoke/method/a.rbi +4 -0
  93. data/smoke/method/b.rb +29 -0
  94. data/smoke/module/a.rb +3 -3
  95. data/smoke/module/a.rbi +9 -0
  96. data/smoke/module/b.rb +2 -2
  97. data/smoke/module/c.rb +1 -1
  98. data/smoke/module/d.rb +5 -0
  99. data/smoke/module/e.rb +13 -0
  100. data/smoke/module/f.rb +13 -0
  101. data/smoke/rescue/a.rb +62 -0
  102. data/smoke/super/a.rb +2 -2
  103. data/smoke/type_case/a.rb +35 -0
  104. data/smoke/yield/a.rb +2 -2
  105. data/stdlib/builtin.rbi +463 -24
  106. data/steep.gemspec +3 -2
  107. metadata +91 -29
  108. data/lib/steep/annotation.rb +0 -223
  109. data/lib/steep/signature/class.rb +0 -450
  110. data/lib/steep/signature/extension.rb +0 -51
  111. data/lib/steep/signature/interface.rb +0 -49
  112. data/lib/steep/types/any.rb +0 -31
  113. data/lib/steep/types/class.rb +0 -27
  114. data/lib/steep/types/instance.rb +0 -27
  115. data/lib/steep/types/merge.rb +0 -32
  116. data/lib/steep/types/name.rb +0 -57
  117. data/lib/steep/types/union.rb +0 -42
  118. data/lib/steep/types/var.rb +0 -38
  119. data/lib/steep/types.rb +0 -4
@@ -1,450 +0,0 @@
1
- module Steep
2
- module Signature
3
- module Members
4
- class InstanceMethod
5
- # @implements Steep__SignatureMember__Method
6
-
7
- # @dynamic name
8
- attr_reader :name
9
- # @dynamic types
10
- attr_reader :types
11
-
12
- attr_reader :constructor
13
-
14
- def initialize(name:, types:, constructor:)
15
- @name = name
16
- @types = types
17
- @constructor = constructor
18
- end
19
-
20
- def ==(other)
21
- other.is_a?(self.class) && other.name == name && other.types == types && other.constructor == constructor
22
- end
23
- end
24
-
25
- class ModuleMethod
26
- # @implements Steep__SignatureMember__Method
27
-
28
- # @dynamic name
29
- attr_reader :name
30
- # @dynamic types
31
- attr_reader :types
32
- attr_reader :constructor
33
-
34
- def initialize(name:, types:, constructor:)
35
- @name = name
36
- @types = types
37
- @constructor = constructor
38
- end
39
-
40
- def ==(other)
41
- other.is_a?(self.class) && other.name == name && other.types == types && other.constructor == constructor
42
- end
43
- end
44
-
45
- class ModuleInstanceMethod
46
- # @implements Steep__SignatureMember__Method
47
-
48
- # @dynamic name
49
- attr_reader :name
50
- # @dynamic types
51
- attr_reader :types
52
- attr_reader :constructor
53
-
54
- def initialize(name:, types:, constructor:)
55
- @name = name
56
- @types = types
57
- @constructor = constructor
58
- end
59
-
60
- def ==(other)
61
- other.is_a?(self.class) && other.name == name && other.types == types && other.constructor == constructor
62
- end
63
- end
64
-
65
- class Include
66
- # @implements Steep__SignatureMember__Include
67
-
68
- # @dynamic name
69
- attr_reader :name
70
-
71
- def initialize(name:)
72
- @name = name
73
- end
74
-
75
- def ==(other)
76
- other.is_a?(Include) && other.name == name
77
- end
78
- end
79
-
80
- class Extend
81
- # @implements Steep__SignatureMember__Extend
82
-
83
- # @dynamic name
84
- attr_reader :name
85
-
86
- def initialize(name:)
87
- @name = name
88
- end
89
-
90
- def ==(other)
91
- other.is_a?(Extend) && other.name == name
92
- end
93
- end
94
- end
95
-
96
- module WithMethods
97
- # @implements Steep__Signature__WithMethods
98
-
99
- def instance_methods(assignability:, klass:, instance:, params:)
100
- methods = super
101
-
102
- hash = type_application_hash(params)
103
-
104
- members.each do |member|
105
- case member
106
- when Members::Include
107
- # @type var include_member: Steep__SignatureMember__Include
108
- include_member = member
109
- module_signature = assignability.lookup_included_signature(include_member.name)
110
- merge_methods(methods, module_signature.instance_methods(assignability: assignability,
111
- klass: klass,
112
- instance: instance,
113
- params: module_signature.type_application_hash(include_member.name.params)))
114
-
115
- end
116
- end
117
-
118
- members.each do |member|
119
- case member
120
- when Members::InstanceMethod, Members::ModuleInstanceMethod
121
- # @type var method_member: Steep__SignatureMember__Method
122
- method_member = member
123
- method_types = method_member.types.map {|type| type.substitute(klass: klass, instance: instance, params: hash) }
124
-
125
- attributes = [].tap do |attrs|
126
- attrs.push(:constructor) if method_member.constructor
127
- end
128
-
129
- merge_methods(methods,
130
- method_member.name => Steep::Interface::Method.new(types: method_types,
131
- super_method: nil,
132
- attributes: attributes))
133
- end
134
- end
135
-
136
- extensions = assignability.lookup_extensions(name)
137
- extensions.each do |extension|
138
- extension_methods = extension.instance_methods(assignability: assignability, klass: klass, instance: instance, params: [])
139
- merge_methods(methods, extension_methods)
140
- end
141
-
142
- methods
143
- end
144
-
145
- def module_methods(assignability:, klass:, instance:, params:, constructor:)
146
- methods = super
147
-
148
- members.each do |member|
149
- case member
150
- when Members::Include
151
- module_signature = assignability.lookup_included_signature(member.name)
152
- merge_methods(methods, module_signature.module_methods(assignability: assignability,
153
- klass: klass,
154
- instance: instance,
155
- params: module_signature.type_application_hash(member.name.params),
156
- constructor: constructor))
157
- when Members::Extend
158
- module_signature = assignability.lookup_included_signature(member.name)
159
- merge_methods(methods, module_signature.instance_methods(assignability: assignability,
160
- klass: klass,
161
- instance: instance,
162
- params: module_signature.type_application_hash(member.name.params)))
163
- end
164
- end
165
-
166
- members.each do |member|
167
- case member
168
- when Members::ModuleInstanceMethod, Members::ModuleMethod
169
- # @type var method_member: Steep__SignatureMember__Method
170
- method_member = member
171
- method_types = method_member.types.map {|type| type.substitute(klass: klass, instance: instance, params: {}) }
172
- merge_methods(methods,
173
- method_member.name => Steep::Interface::Method.new(types: method_types,
174
- super_method: nil,
175
- attributes: []))
176
- end
177
- end
178
-
179
- if is_class? && constructor
180
- instance_methods = instance_methods(assignability: assignability, klass: klass, instance: instance, params: params)
181
- new_method = if instance_methods[:initialize]
182
- types = instance_methods[:initialize].types.map do |method_type|
183
- method_type.updated(return_type: instance)
184
- end
185
- Steep::Interface::Method.new(types: types, super_method: nil, attributes: [])
186
- else
187
- Steep::Interface::Method.new(types: [Steep::Interface::MethodType.new(type_params: [],
188
- params: Steep::Interface::Params.empty,
189
- block: nil,
190
- return_type: instance)],
191
- super_method: nil,
192
- attributes: [])
193
- end
194
- methods[:new] = new_method
195
- end
196
-
197
- methods
198
- end
199
-
200
- def merge_methods(methods, hash)
201
- hash.each_key do |name|
202
- new_method = hash[name]
203
- old_method = methods[name]
204
- attributes = (new_method.attributes + (old_method&.attributes || [])).sort.uniq
205
-
206
- methods[name] = Steep::Interface::Method.new(types: new_method.types,
207
- super_method: old_method,
208
- attributes: attributes)
209
- end
210
- end
211
- end
212
-
213
- module WithMembers
214
- # @implements Steep__Signature__WithMembers
215
- def each_type
216
- if block_given?
217
- members.each do |member|
218
- case member
219
- when Members::InstanceMethod, Members::ModuleMethod, Members::ModuleInstanceMethod
220
- # @type var method_member: Steep__SignatureMember__Method
221
- method_member = member
222
- method_member.types.each do |method_type|
223
- method_type.params.each_type do |type|
224
- yield type
225
- end
226
- yield method_type.return_type
227
- if method_type.block
228
- method_type.block.params.each_type do |type|
229
- yield type
230
- end
231
- yield method_type.block.return_type
232
- end
233
- end
234
- when Members::Include, Members::Extend
235
- # @type var mixin_member: _Steep__SignatureMember__Mixin
236
- mixin_member = member
237
- yield mixin_member.name
238
- else
239
- raise "Unknown member: #{member.class.inspect}"
240
- end
241
- end
242
- else
243
- enum_for :each_type
244
- end
245
- end
246
-
247
- def validate_mixins(assignability, interface)
248
- members.each do |member|
249
- if member.is_a?(Members::Include)
250
- module_signature = assignability.lookup_included_signature(member.name)
251
-
252
- if module_signature.self_type
253
- self_type = module_signature.self_type.substitute(klass: Types::Name.module(name: name),
254
- instance: Types::Name.instance(name: name),
255
- params: {})
256
- self_interface = assignability.resolve_interface(self_type.name, member.name.params)
257
-
258
- unless assignability.test_interface(interface, self_interface, [])
259
- assignability.errors << Errors::InvalidSelfType.new(signature: self, member: member)
260
- end
261
- end
262
- end
263
- end
264
- end
265
- end
266
-
267
- module WithParams
268
- # @implements Steep__Signature__WithParams
269
-
270
- def type_application_hash(args)
271
- Hash[params.zip(args)]
272
- end
273
- end
274
-
275
- class Module
276
- # @implements Steep__Signature__Module
277
-
278
- # @dynamic name
279
- attr_reader :name
280
- # @dynamic params
281
- attr_reader :params
282
- # @dynamic members
283
- attr_reader :members
284
- # @dynamic self_type
285
- attr_reader :self_type
286
-
287
- prepend WithMethods
288
- include WithMembers
289
- include WithParams
290
-
291
- def initialize(name:, params:, members:, self_type:)
292
- @name = name
293
- @members = members
294
- @params = params
295
- @self_type = self_type
296
- end
297
-
298
- def ==(other)
299
- other.is_a?(Module) && other.name == name && other.params == params && other.members == members && other.self_type == self_type
300
- end
301
-
302
- def instance_methods(assignability:, klass:, instance:, params:)
303
- {}
304
- end
305
-
306
- def module_methods(assignability:, klass:, instance:, params:, constructor:)
307
- {}
308
- end
309
-
310
- def each_type
311
- if block_given?
312
- yield self_type if self_type
313
- super do |type|
314
- yield type
315
- end
316
- else
317
- enum_for :each_type
318
- end
319
- end
320
-
321
- def validate(assignability)
322
- each_type do |type|
323
- assignability.validate_type_presence self, type
324
- end
325
-
326
- interface = assignability.resolve_interface(TypeName::Instance.new(name: name),
327
- params.map {|x| Types::Var.new(name: x) })
328
-
329
- validate_mixins(assignability, interface)
330
-
331
- # FIXME: There is no check for initializer compatibility
332
- if interface.methods.values.any? {|method| method.attributes.include?(:constructor) }
333
- assignability.errors << Signature::Errors::ConstructorNoCheck.new(signature: self)
334
- end
335
- end
336
-
337
- def is_class?
338
- false
339
- end
340
- end
341
-
342
- class Class
343
- # @implements Steep__Signature__Class
344
-
345
- # @dynamic name
346
- attr_reader :name
347
- # @dynamic params
348
- attr_reader :params
349
- # @dynamic members
350
- attr_reader :members
351
- # @dynamic super_class
352
- attr_reader :super_class
353
-
354
- prepend WithMethods
355
- include WithMembers
356
- include WithParams
357
-
358
- def initialize(name:, params:, members:, super_class:)
359
- @name = name
360
- @members = members
361
- @params = params
362
- @super_class = super_class
363
- end
364
-
365
- def ==(other)
366
- other.is_a?(Class) && other.name == name && other.params == params && other.members == members && other.super_class == super_class
367
- end
368
-
369
- def instance_methods(assignability:, klass:, instance:, params:)
370
- if self.name == :BasicObject
371
- {}
372
- else
373
- super_class = self.super_class || Types::Name.instance(name: :Object)
374
- signature = assignability.lookup_super_class_signature(super_class)
375
-
376
- hash = type_application_hash(params)
377
- super_class_params = super_class.params.map do |type|
378
- type.substitute(klass: klass, instance: instance, params: hash)
379
- end
380
-
381
- signature.instance_methods(assignability: assignability, klass: klass, instance: instance, params: super_class_params)
382
- end
383
- end
384
-
385
- def module_methods(assignability:, klass:, instance:, params:, constructor:)
386
- signature = assignability.lookup_class_signature(Types::Name.instance(name: :Class))
387
- class_methods = signature.instance_methods(assignability: assignability,
388
- klass: klass,
389
- instance: instance,
390
- params: [instance])
391
- if self.name == :BasicObject
392
- class_methods
393
- else
394
- super_class = self.super_class || Types::Name.instance(name: :Object)
395
- signature = assignability.lookup_super_class_signature(super_class)
396
-
397
- hash = type_application_hash(params)
398
- super_class_params = super_class.params.map do |type|
399
- type.substitute(klass: klass, instance: instance, params: hash)
400
- end
401
-
402
- class_methods.merge!(signature.module_methods(assignability: assignability,
403
- klass: klass,
404
- instance: instance,
405
- params: super_class_params,
406
- constructor: constructor))
407
- end
408
- end
409
-
410
- def each_type
411
- if block_given?
412
- yield super_class if super_class
413
- super do |type|
414
- yield type
415
- end
416
- else
417
- enum_for :each_type
418
- end
419
- end
420
-
421
- def validate(assignability)
422
- each_type do |type|
423
- assignability.validate_type_presence self, type
424
- end
425
-
426
- interface = assignability.resolve_interface(TypeName::Instance.new(name: name),
427
- params.map {|x| Types::Var.new(name: x) },
428
- constructor: true)
429
-
430
- interface.methods.each_key do |method_name|
431
- method = interface.methods[method_name]
432
- if method.super_method
433
- assignability.validate_method_compatibility(self, method_name, method)
434
- end
435
- end
436
-
437
- validate_mixins(assignability, interface)
438
-
439
- # FIXME: There is no check for initializer compatibility
440
- if interface.methods.values.any? {|method| method.attributes.include?(:constructor) }
441
- assignability.errors << Signature::Errors::ConstructorNoCheck.new(signature: self)
442
- end
443
- end
444
-
445
- def is_class?
446
- true
447
- end
448
- end
449
- end
450
- end
@@ -1,51 +0,0 @@
1
- module Steep
2
- module Signature
3
- class Extension
4
- # @implements Steep__Signature__Extension
5
-
6
- def initialize(module_name:, extension_name:, members:)
7
- @module_name = module_name
8
- @extension_name = extension_name
9
- @members = members
10
- end
11
-
12
- def module_name; @module_name; end
13
- def extension_name; @extension_name; end
14
- def members; @members; end
15
-
16
- def ==(other)
17
- # @type var other_: Steep__Signature__Extension
18
- other_ = other
19
- other.is_a?(self.class) &&
20
- other_.module_name == module_name &&
21
- other_.extension_name == extension_name &&
22
- other_.members == members
23
- end
24
-
25
- def name
26
- :"#{module_name} (#{extension_name})"
27
- end
28
-
29
- include WithMembers
30
- prepend WithMethods
31
-
32
- def validate(assignability)
33
- each_type do |type|
34
- assignability.validate_type_presence self, type
35
- end
36
- end
37
-
38
- def instance_methods(assignability:, klass:, instance:, params:)
39
- {}
40
- end
41
-
42
- def module_methods(assignability:, klass:, instance:, params:)
43
- {}
44
- end
45
-
46
- def type_application_hash(args)
47
- {}
48
- end
49
- end
50
- end
51
- end
@@ -1,49 +0,0 @@
1
- module Steep
2
- module Signature
3
- class Interface
4
- # @implements Steep__Signature__Interface
5
- # @type const Hash: Hash.class
6
- # @type const Interface: Steep__Signature__Interface.class
7
- # @type const Steep::Interface: Steep__Interface.class
8
- # @type const Steep::Interface::Method: Steep__Method.class
9
-
10
- # @dynamic name
11
- attr_reader :name
12
- # @dynamic params
13
- attr_reader :params
14
- # @dynamic methods
15
- attr_reader :methods
16
-
17
- def initialize(name:, params:, methods:)
18
- @name = name
19
- @params = params
20
- @methods = methods
21
- end
22
-
23
- def ==(other)
24
- # @type var other_: Steep__Signature__Interface
25
- other_ = other
26
- other_.is_a?(Interface) && other_.name == name && other_.params == params && other_.methods == methods
27
- end
28
-
29
- def to_interface(klass:, instance:, params:)
30
- raise "Invalid type application: expected: #{self.params.size}, actual: #{params.size}" if params.size != self.params.size
31
-
32
- # @type var map: Hash<Symbol, Steep__Type>
33
- map = Hash[self.params.zip(params)]
34
- Steep::Interface.new(name: name,
35
- params: params,
36
- methods: methods.transform_values {|method|
37
- types = method.map {|method_type|
38
- method_type.substitute(klass: klass, instance: instance, params: map)
39
- }
40
- Steep::Interface::Method.new(types: types, super_method: nil, attributes: [])
41
- })
42
- end
43
-
44
- def validate(assignability)
45
-
46
- end
47
- end
48
- end
49
- end
@@ -1,31 +0,0 @@
1
- module Steep
2
- module Types
3
- class Any
4
- # @implements Steep__Types__Any
5
-
6
- def ==(other)
7
- other.is_a?(Any)
8
- end
9
-
10
- def hash
11
- self.class.hash
12
- end
13
-
14
- def eql?(other)
15
- other == self
16
- end
17
-
18
- def closed?
19
- true
20
- end
21
-
22
- def substitute(klass:, instance:, params:)
23
- self
24
- end
25
-
26
- def to_s
27
- "any"
28
- end
29
- end
30
- end
31
- end
@@ -1,27 +0,0 @@
1
- module Steep
2
- module Types
3
- class Class
4
- # @implements Steep__Types__Class
5
-
6
- def ==(other)
7
- other.is_a?(Class)
8
- end
9
-
10
- def hash
11
- self.class.hash
12
- end
13
-
14
- def eql?(other)
15
- self == other
16
- end
17
-
18
- def closed?
19
- false
20
- end
21
-
22
- def substitute(klass:, instance:, params:)
23
- klass
24
- end
25
- end
26
- end
27
- end
@@ -1,27 +0,0 @@
1
- module Steep
2
- module Types
3
- class Instance
4
- # @implements Steep__Types__Instance
5
-
6
- def ==(other)
7
- other.is_a?(Instance)
8
- end
9
-
10
- def eql?(other)
11
- self == other
12
- end
13
-
14
- def hash
15
- self.class.hash
16
- end
17
-
18
- def closed?
19
- false
20
- end
21
-
22
- def substitute(klass:, instance:, params:)
23
- instance
24
- end
25
- end
26
- end
27
- end
@@ -1,32 +0,0 @@
1
- module Steep
2
- module Types
3
- class Merge
4
- # @implements Steep__Types__Merge
5
-
6
- # @dynamic types
7
- attr_reader :types
8
-
9
- def initialize(types:)
10
- @types = types
11
- end
12
-
13
- def ==(other)
14
- # @type var other_: Steep__Types__Merge
15
- other_ = other
16
- other_.is_a?(self.class) && other_.types == types
17
- end
18
-
19
- def hash
20
- self.class.hash ^ types.hash
21
- end
22
-
23
- def eql?(other)
24
- other == self
25
- end
26
-
27
- def to_s
28
- types.join(" + ")
29
- end
30
- end
31
- end
32
- end